Question

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?

Was it helpful?

Solution

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:

  1. Use the has_and_belongs_to_many method in both models to describe the relationship;
  2. Manually create a "join" model and then give both 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);
  3. A has_many ... :through style, like you mentioned

Note 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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top