Reputation: 69
I'm working on a gem to export a small portion of related ActiveRecord objects.
Here's how I'm currently finding parents & children.
# 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
Is there a better way to find these relationships? This works ok, but distant relationships, like :through, I have to specify manually.
Upvotes: 0
Views: 49
Reputation: 11647
Use class.reflections
. It returns information about a model's relationships.
Imagine you have this simple set up:
# user.rb
belongs_to :user_type
has_many :user_logs
If you call User.reflections
you will get a hash similar to the following:
{
:user_type => <Reflection @macro=:belongs_to, etc. ...>,
:user_logs => <Reflection @macro=:has_many, etc. ...>
}
The reflection is an instance of ActiveRecord::Reflection::AssociationReflection
or ActiveRecord::Reflection::ThroughReflection
. It contains information about which model it references, what the options are (like dependent => :destroy
), what type of association it is (the @macro
in my example), etc.
Upvotes: 1
Reputation: 6870
I'm not exactly sure if that's what you're looking for but ActiveRecord has helpers to do this. In your models:
#school.rb
has_many :classrooms
#classroom.rb
belongs_to :school
You can now use pretty much anywhere:
school = random_classroom.school
classrooms = school.classrooms
For a has_many :through
relationship:
# school.rb
has_many :students,
:through => :classrooms
Upvotes: 0