2016-05-17 93 views
0

我正在創建一個gem來導出一小部分相關的ActiveRecord對象。有沒有更好的方法來查找ActiveRecord對象的孩子和父母?

以下是我目前如何找到父母&孩子。

# belongs_to, based on column names with an _id suffix 
def belongs_to_relations(ar_instance) 
    columns = ar_instance.class.column_names 
    parents = columns.map{ |c| c if c =~ /_id/ }.reject{ |c| c.nil? } 
    parents.map!{ |parents| parents.gsub('_id', '') } 
end 

# has_many, based on existence of a xxx_id column in other tables 
def has_many_relations(ar_instance) 
    column_name = "#{ar_instance.class.name.underscore}_id" 
    descendents = ActiveRecord::Base.connection.tables 
    descendents.reject!{ |table| false unless table.classify.constantize rescue true } 
    descendents.reject!{ |table| true unless table.classify.constantize.column_names.include?(column_name) } 
end 

有沒有更好的方法來找到這些關係?這工作,但遙遠的關係,如:通過,我必須手動指定。

回答

1

使用class.reflections。它返回關於模型關係的信息。

想象一下,你有這個簡單的設置:

# user.rb 
belongs_to :user_type 
has_many :user_logs 

如果你打電話User.reflections你會得到類似下面的哈希:

{ 
    :user_type => <Reflection @macro=:belongs_to, etc. ...>, 
    :user_logs => <Reflection @macro=:has_many, etc. ...> 
} 

反射是ActiveRecord::Reflection::AssociationReflectionActiveRecord::Reflection::ThroughReflection一個實例。它包含有關哪種型號的參考信息,選項是什麼(如dependent => :destroy),它是什麼類型的聯繫(在我的示例中爲@macro)等。

0

我不完全相信如果這就是你要找的,但ActiveRecord有助手來做到這一點。 在你的模型:

#school.rb 
has_many :classrooms 

#classroom.rb 
belongs_to :school 

您現在可以使用幾乎任何地方:

school = random_classroom.school 
classrooms = school.classrooms 

對於has_many :through關係:

# school.rb 
    has_many :students, 
      :through => :classrooms 
相關問題