【问题标题】:Saving a rails has_many association using multiple keys使用多个键保存 rails has_many 关联
【发布时间】:2013-10-01 14:22:57
【问题描述】:

我有以下型号:

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

我正在添加recommendations recommendations_set 像这样:

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
            )

这按预期工作,但是我的问题是我有多个recommendation_sets,它们属于多个products,每个recommendation_sets 可能有相同的recommendation。通过像我目前所做的那样将每个recommendation 保存到recommendation_set,如果两个recommendation_sets 具有相同的recommendation,则只有一组将添加recommendation。是否可以使用辅助 ID 将每个 recommendation 保存到多个 recommendation_sets,例如通过 recommendation_id_and_product_id 保存,或者我需要将此关系更改为 has_many :through

【问题讨论】:

  • 顺便说一句,对于第一行代码,如果想简化一点,可以使用first_or_create方法。所以你会做这样的事情:Product.where(:wmt_id=&gt;product).first_or_create(ItemData.get_product_data(product)。这也适用于更下方的ProductRecommendationSet 行;而不是使用那么长的find_or_create_by_foo_and_bar_and_baz_and....,您可以将它们全部填充到.where,然后调用first_or_create
  • 此外,在ProductRecommendationSet 创建行的末尾,括号内还有一个额外的逗号。此外,在创建块的第二行,您有 find_by_rec_idcreate 自己;在那条线上正在创建哪些模型?最后,在同一块中的第 4 行,您有一个名为 sec_set 的变量,但我在任何地方都看不到。这是一个错字还是在其他地方定义的变量?
  • 最后,您能否澄清一下我对您问题的解释是否正确:我有 2 个推荐集(RS1 和 RS2),它们都指向同一个推荐 (R)。您是说,鉴于上面的代码,如果您尝试保存这两个推荐集,则只有其中一个被保存(意思是,RS1 被保存,RS2 没有)?
  • 感谢您的建议!澄清:我有两个推荐集 RS1 和 RS2 以及属于它们的多个推荐,R1..Rn。如何在将 R1 保存到 RS2 的同时将 R1 保存到 RS1。现在发生的事情是 R1 被保存到 RS2 而不是 RS1,因为 R1 只能存储 RS2 的 id(我的推荐表上只有一个参考 id 列)。我想我可能不得不使用 has_many through 关系,这样我就可以使用多个推荐集 ID 创建关联。
  • 哦,好吧,我想我明白了。我要发布一个答案;让我知道我是否理解正确。

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2 model-associations


【解决方案1】:

根据您的澄清,我认为您在RecommendationSetRecommendation 之间基本上存在多对多关系。目前,您有一对多。

有几个选项:

  1. 在两个模型中都使用has_and_belongs_to_many方法来描述关系;
  2. 手动创建一个“连接”模型,然后将RecommendationSetRecommendation 一个has_many 分配给这个连接模型(连接模型中有两条对应的belongs_to 行指向另外两个模型);
  3. has_many ... :through 风格,就像你提到的那样

请注意,前两个选项要求您有一个连接表。

如果您需要有关连接表/模型的更多信息,我倾向于使用第二个选项。否则,第一个或第三个都是完全有效的。

RailsCasts 的 Ryan Bates 在这里制作了一集:http://railscasts.com/episodes/47-two-many-to-many

还有一些来自 Rails 文档的更多信息:http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Many-to-many

简而言之,如果您不需要有关加入的额外信息,我认为您对 has_many ... :through 的想法非常好。

让我知道这是否有帮助

【讨论】:

    猜你喜欢
    • 2011-07-14
    • 1970-01-01
    • 2016-08-24
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多