I have the following associations in place:
class User < ActiveRecord::Base
has_many :shopping_requests
has_many :recommendations, :through => :shopping_requests
end
class ShoppingRequest < ActiveRecord::Base
belongs_to :user
has_many :recommendations
end
class Recommendation < ActiveRecord::Base
belongs_to :shopping_request
has_one :user, :through => :shopping_requests
end
Now I need to add a Compliment class. A user can compliment another user (so I have a user_from_id and a user_to_id). A compliment can be given for either a shopping request and/or a recommendation; and there's no limit (a user can be given several compliments by the same user or other users for any number of shopping requests as well as for recommendations).
I do know to make the Compliment polymorphic but not sure what is the best way to set it up in relation to users/shopping requests/recommendations.
I want to be able to run queries like this:
- user_to_id.compliments (to get all the compliments for the user);
- user_to_id.shopping_request.compliments (to get all that user's compliments for a particular shopping request;
- user_to_id.recommendation.compliments (to get all that user's compliments for a particular recommendation; for this particular query, running user_to_id.shopping_request.recommendation.compliments is fine too);
- user_from_id.compliments (to get all the compliments that a user gave another);
- user_from_id.shopping_request.compliments (to get all the compliments given by this user for a particular shopping_request), etc....
So what is the best way to set up the association for the Compliment class?
Here's my first swing. Your already-written code works, and I haven't reproduced it here.
I made one change to your database as you've defined it. Compliment knows which Complimentable it belongs to, and since each Complimentable knows its User, saving the complemented-User is redundant. You could choose to add the lines...
...but I don't think I would.
Those are the associations you'll need to create. However, some of your desired method calls aren't specific enough. One example:
Because what you've written is an instance method for User, we can assume the User is known. However, since a User can have many ShoppingRequests, it isn't possible, through what you've written, to hone in on one specific request to show Compliments for.