【问题标题】:Rails mutliple has_one relationships as a has_manyRails 将多个 has_one 关系作为 has_many
【发布时间】:2015-03-10 22:26:41
【问题描述】:

我有一个场景,我需要有多个 has_one 关系,并且能够通过一个关系一次访问它们。

目前我有一张 STI 表,我们将其命名为 Animals。 有子类:狮子、猫鼬、野猪

并且它们都需要与多个 Group 对象相关。
所以一个 Lion 可以属于多个组,但一个组可能只有一个 Lion 相关。

我想限制并专门指一种狮子、猫鼬和野猪。 我尝试了一个简单的桥表,has_many :animals,通过::associated_animals。但是似乎没有一个简单的方法来拉出 group.lion。我也尝试过做多个 has_one :lion/:meerkat/:boar 关系,但没有明显的方法来做 group.animals。

是否有一种 STI 方法可以通过默认的 rails 关联来获得此功能,还是我必须将 has_one :lion 和 has_many :animals 结合起来?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    你有没有这样尝试过: app/models/animal.rb

    class Animal < ActiveRecord::Base                                                                                                                                                                                                          
      belongs_to :group                                                                                                                                                                                                                        
    end                                                                                                                                                                                                                                        
    
    class Lion < Animal; end                                                                                                                                                                                                                   
    class Meerkat < Animal; end
    

    当然,您可以将 Lion 和 Meerkat 类拆分为单独的 ruby​​ 文件

    app/models/group.rb

     class Group < ActiveRecord::Base                                                                                                                                                                                                           
       has_many :animals                                                                                                                                                                                                                    
       has_one :lion                                                                                                                                                                                                                        
       has_one :meerkat                                                                                                                                                                                                                     
     end  
    

    运行迁移后,您的架构应如下所示: db/schema.rb

    ActiveRecord::Schema.define(version: 20150309234835) do                                                                                                                                                                                    
    
      create_table "animals", force: :cascade do |t|                                                                                                                                                                                           
        t.string   "name"                                                                                                                                                                                                                                                                                                                                                                                                                                          
        t.string   "type"                                                                                                                                                                                                                      
        t.datetime "created_at", null: false                                                                                                                                                                                                   
        t.datetime "updated_at", null: false                                                                                                                                                                                                   
        t.integer  "group_id"                                                                                                                                                                                                                  
      end                                                                                                                                                                                                                                      
    
      create_table "groups", force: :cascade do |t|                                                                                                                                                                                            
        t.string   "name"                                                                                                                                                                                                                      
        t.datetime "created_at", null: false                                                                                                                                                                                                   
        t.datetime "updated_at", null: false                                                                                                                                                                                                   
      end                                                                                                                                                                                                                                      
    
    end 
    

    现在您应该可以使用组编写查询了:

    g = Group.find(1)
    g.animals
    g.lion
    Lion.first.group
    Animal.last.group
    

    【讨论】:

    • 我添加了以下内容。 'belongs_to :lion, polymorphic: true' 并将类型列附加到所有 3 种类型的组。仍然无法工作的部分是 has_many :animals。它正在寻找动物表上的 group_id,其中没有。
    • 那你为什么不把group_id列加到animals表中呢?
    • 动物可以分成许多组,但一个组中每种类型只能有1个。所以把 ID 放在那张桌子上是行不通的。
    • 那么你必须在两个模型中使用 has_and_belongs_to_many 关系 - 动物和组guides.rubyonrails.org/…
    • has_and_belongs_to_many 关系不允许验证只有一只狮子,对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多