2016-05-17 62 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 
相关问题