Rails Association Help - Do I use Polymorphic Association? - ruby-on-rails

I need help determining what kind of associations I should use for the following 3 models. Below are the tables and what I think the current association is. Please let me know if there is a better way to achieve below. Thanks
How the tables should look.
User Table
id
Meal Table
id
Comment Table
user_id
Meal_id
Here is what I think the associations look, but this may change depending on the type of association is used.
User
has_many :comments
Meal
has_many :comments
Comment
belongs_to :user
belongs_to :meal

That sound like a good way to do it.
I would rename the belongs_to :user association to belongs_to :author, :class_name => "User" to be more explicit about the role the association plays in your system.
If you want to add more models to comment on, you should use polymorphic associations.

Related

Model Structure & has_many Association Migrations

I'm trying to set up models in such a way that Users can create Lessons and then other users can sign up for them.
Right now my models are set up like this:
class Lesson < ApplicationRecord
belongs_to :teacher, class_name: 'User'
has_many :students, class_name: 'User'
end
class User < ApplicationRecord
has_many :lessons
has_many :students, :through => :lessons
end
I want to be able to access the users signed up for a lesson by #lesson.students for example. I'd also like to be able to get all the lessons that a student is participating in (can't really see how I'd do this with my current set up).
Are my model associations right for how I'd like to use them? If so, how can I create the migrations to add the necessary references to my database models?
If you want the ability to create nested resources from it's parents then you have to add:
accepts_nested_attributes_for
to the parent model.
Also, I recommend you to read how to set up has_many through relationships, you need a join model for rails to do its magic and link the 2 models
Once you set everything up, create the join model (with it's respective foreign keys, one for lesson and the other for user) rails will take care of the associations between the models, allowing you to do things like:
User.last.lessons #lessons created by the last user
and
Lesson.first.users #users subscribed to a lesson, in this case the first one

Understanding customized has_many association

Given association in User class:
has_many :followers, through: :follows_as_fallowable,
source: :user
It returns user instances that follow a given user. But when i started to dig deeper i realized that i don't completely understand why does this association(user.followers) returns User objects.
Based on what? I know that it can deduce by name of the association or class_name hash argument, but neither of these actually matters in this case.
I don't have Follower model and i have not provided class_name attribute.
Source parameter just say that it should search by user column in join table.
So how does Rails know that it should select from Users table?
EDIT:
follow_as_followable is another association in User model:
has_many :follows_as_fallowable, class_name: 'Follow', as: :followable
Rails would be picking up knowledge of the User through the follows_as_fallowable relationship, using the association name specified by :source, which is :user (e.g. the User model).
While it's not show in the question, it's likely that the model containing follows_as_fallowable has a belongs_to :user relationship defined, hence the use of source: :user to specify which relationship through which to navigate.
You can see more information in The has_many :through Association section of the Active Record Associations guide.

Rails migration join table for multiple associations of the same model using different names

In my project, I have this simple association set up:
class Episode < ActiveRecord::Base
belongs_to :game_master, :class_name => 'CastMember'
has_and_belongs_to_many :players, :class_name => 'CastMember'
end
class CastMember < ActiveRecord::Base
has_and_belongs_to_many :episodes
end
I was wondering what the join table for these might be.
At first, I thought a cast_members_episodes table would be enough, but after thinking about it for a bit, it wouldn't make sense, as it wouldn't be able to differentiate between game_master and players.
Any ideas?
Yes, cast_members_episodes table to handle the many-to-many relation of players and episodes.
And, add a column game_master_id to episodes table to handle the relation of game_master and episodes.

Rails Associations Planning

I'm still making my way with Rails and I have a question about associations.
I'm building a fitness website and I want to have users track their workouts. I'm a bit unsure as to how the associations should go. What follows is what I currently have.
A Workout is made up of a group of exercises. The user would create a workout object to save all the exercises together so as to not have to repeat the creation process every time. On top of that I don't want them to have to re-create exercises to add it to a new workout. So, both workouts and exercises would belong to a user.
My planned associations are this.
Workout
belongs_to :user
has_many :exercises, :through => :routines
Exercise
belongs_to :user
has_many :workouts, :through => :routines
Routines
belongs_to :workout
belongs_to :exercise
User
has_many :workouts
has_many :exercises
//the rest of the user associations
I think this is correct, but having both workout and exercise belonging to the user seems somewhat redundant to me. Is this the best setup or is there another way to associate these things? Any help is appreciated.
I see there is no need of having Routines there.And you need to tweak your Associations.
How about like this
Workout
belongs_to :user
belongs_to :exercise
User
has_many :exercises
has_many :workouts :through => exercises
Exercise
has_many :workouts
belongs_to :user
Personally, this seems a bit more logical to me:
class User
has_many :workouts
class Workout
belongs_to :user
has_and_belongs_to_many :exercises
class Exercise
has_and_belongs_to_many :workouts
In my opinion exercises only belong to one or more workouts and it has little to do with an user. Therefore I would omit the association between users and exercises.
Since workouts can share similar exercises there is a many-to-many relationship between them. Usually I go for a has_many, through relationship in these cases, but since you do not mention possible additional attributes for the join model has_and_belongs_to_many with a join table should suffice.
EDIT: The associations are probably a bit more complex the more you think about it. For example, a workout can actually belong to multiple users. I think it would be best to go to the drawing board and draw the associations and the attributes per model.

has_many relation doesn't seems right or logical in business perceptive, needed some thing like belongs_to_many?

My situation is like this.
Company has many users and users may belongs to many companies.
And current implementation is something like below.
class Company
has_many :employments
has_many :users, :through => :employments
end
class Employment
belongs_to :company
belongs_to :user
end
class User
has_many :employments
has_many :companies, :through => :employments #This doesn't looks correct
end
It works, but "user has many companies" doesn't looks logically meaningful. It must be some thing like belongs_to_many companies.
Do I need to use has_and_belongs_to_many?
Can some one please suggest the right way for representing these relationships?
If you are not going to add some special behaviour to Employment class and you don't really need it, then you should propably better use has_and_belongs_to_many. This way it will still have some table called CompanyUser, but there will not be any such class in the code.
Added:
There are just 3 possbile conections between 2 objects: 1-to-1, 1-to-many and many-to-many. Rails indicates with has_* or belongs_to what of the 2 objects will get a foreign key. So:
1-to-1:
has_one and belongs_to are used. The object with belongs_to gets the FK.
1-to-many:
has_many and belongs_to are used. The object with belongs_to gets the FK.
many-to-many:
has_many[through] or has_and_belongs_to_many are used in both objects. No-one gets a FK, instead a ConnectionTable is used.
So there is no such thing as belongs_to_many, because it would be the same as has_many - providing the same relation 1-to-many.

Resources