I have the following models:
class Product < ActiveRecord::Base
has_many :product_recommendation_sets, :dependent => :destroy
has_many :recommendation_sets, :through => :product_recommendation_sets
end
class RecommendationSet < ActiveRecord::Base
has_many :product_recommendation_sets, :dependent => :destroy
has_many :products, :through => :product_recommendation_sets
has_many :recommendations
end
class Recommendation < ActiveRecord::Base
belongs_to :recommendation_set
end
And am adding recommendations
recommendations_set
like so:
p = Product.find_by_wmt_id(product) || Product.create( ItemData.get_product_data(product) )
recommendation = find_by_rec_id(rec_id) || create( ItemData.get_product_data(rec_id) )
rec_set = RecommendationSet.find_or_create_by_rating_set_id_and_model_version_and_product_id(rating_set.id, model_version, p.id)
sec_set.update_attributes(
:rating_set_id => rating_set.id,
:product_id => p.id,
:model_version => model_version,
:notes => note
)
sec_set.recommendations << recommendation
sec_set.save
prs = ProductRecommendationSet.find_or_create_by_recommendation_set_id_and_rating_set_id_and_product_id(rec_set .id, rating_set.id, p.id,)
prs.update_attributes(
:recommendation_set_id => rec_set.id,
:rating_set_id => rating_set.id,
:product_id => p.id
)
This works as expected, however my problem is that I have multiple recommendation_sets
which belong to multiple products
, and each of the recommendation_sets
may have the same recommendation
. By saving each recommendation
to a recommendation_set
as I am currently doing, if two recommendation_sets
have the same recommendation
, only one of the sets will add that recommendation
. Is there anyway of saving each recommendation
to multiple recommendation_sets
using a secondary id, such as save by recommendation_id_and_product_id
, or would I need to change this releationship to a has_many :through
?
Based on your clarification, I think you basically have a many-to-many relationship between RecommendationSet
and Recommendation
. Presently, you have a one-to-many.
There are a couple of options:
has_and_belongs_to_many
method in both models to describe the relationship;RecommendationSet
and Recommendation
a has_many
to this join model (with two corresponding belongs_to
lines in the join model pointing to the other two models);has_many ... :through
style, like you mentionedNote that the first two options require you to have a join table.
If you require additional information on the join table/model, I tend to go with the 2nd option. Otherwise, either the first or third are perfectly valid.
Ryan Bates of RailsCasts made an episode about this here: http://railscasts.com/episodes/47-two-many-to-many
And some more information from the Rails documentation: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Many-to-many
In short, if you don't need extra info on the join, I think your idea of the has_many ... :through
is perfectly fine.
Let me know whether that helps