将多个has_one关系作为has_many进行Rails

时间:2015-03-09 18:32:07

标签: ruby-on-rails ruby activerecord

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

目前我有一个STI表,我们称之为动物。 有子类:Lion,Meerkat,Boar

他们都需要与多个Group对象相关联 因此,狮友可以分为多个群组,但群组可能只有一个狮子会相关。

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

是否存在通过默认rails关联获得此功能的STI方式,还是我必须同时执行has_one:lion和has_many:animals的组合?

1 个答案:

答案 0 :(得分:0)

您是否尝试过这样: 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 

现在您应该能够使用group编写查询:

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