简体   繁体   English

Rails多个has_one关系作为has_many

[英]Rails mutliple has_one relationships as a has_many

I have a scenario where I need to have multiple has_one relationships and be able to access them all at once through a relationship. 我有一个场景,我需要具有多个has_one关系,并能够通过一个关系立即访问它们。

Currently I have an STI table, we'll call it Animals. 目前,我有一个STI表,我们将其称为Animals。 There are subclasses: Lion, Meerkat, Boar 有子类:Lion,Meerkat,Boar

And they all need to relate to multiple Group objects. 它们都需要与多个Group对象相关。
So a Lion can be in multiple groups, but a Group may only have one Lion related. 因此,狮子可以在多个组中,但是一个组可能只与一个狮子相关。

I want to limit and refer to specifically one Lion, Meerkat and Boar. 我想限制并具体提及一只狮子,猫鼬和野猪。 I've tried a simple bridge table, has_many :animals, through: :associated_animals. 我已经尝试过一个简单的桥接表has_many:animals,通过::associated_animals。 But there doesn't seem to be an easy way to pull out group.lion. 但是似乎没有简单的方法可以退出group.lion。 I've also tried doing multiple has_one :lion/:meerkat/:boar relationships, but there was no obvious way to do group.animals. 我也尝试过做多个has_one:lion /:meerkat /:boar关系,但是没有明显的方法来做group.animals。

Is there an STI way to get this functionality through default rails associations or do I have to do a combination of both the has_one :lion and has_many :animals? 是否有STI方法可以通过默认的rails关联获得此功能,还是必须将has_one:lion和has_many:animals结合起来使用?

Have you tried it like this: app/models/animal.rb 您是否尝试过这样的app/models/animal.rbapp/models/animal.rb

class Animal < ActiveRecord::Base                                                                                                                                                                                                          
  belongs_to :group                                                                                                                                                                                                                        
end                                                                                                                                                                                                                                        

class Lion < Animal; end                                                                                                                                                                                                                   
class Meerkat < Animal; end

Of course you can split out the Lion and Meerkat classes to separate ruby files 当然,您可以将Lion和Meerkat类拆分为单独的ruby文件

app/models/group.rb

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

after you run your migrations your schema should look something like this: db/schema.rb 运行迁移后,您的架构应如下所示: 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 

Now you should be able to write queries using group: 现在,您应该可以使用group编写查询了:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM