has_many things which have many more things which... you get the idea

Say I have the following

class GrandParentThing < ActiveRecord::Base
  has_many :parent_things
end

class ParentThing < ActiveRecord::Base
  has_many :child_things
  belongs_to :grand_parent_thing
end

class ChildThing < ActiveRecord::Base
  belongs_to :parent_thing
end

Are there any built-in methods or plugins to help me get all of the child_things
that a grand_paraent_thing has?

I know how to do the .find to get the information out using a minimal number of
SQL queries but I have a lot of these in my project so I wondered if anyone had
packaged it up yet.

TIA,
Gareth

Try acts_as_nested_set. It allows you to select all children (and
their descendents) with a single query.

http://api.rubyonrails.org/classes/ActiveRecord/Acts/NestedSet/ClassMethods.html

You can use:
has_many :grand_child_things, :through => :parent_things

Gareth Adams wrote:

I think acts_as_nested_set will add more functionality than you want.
Its intent is to provide the full tree, grand_parent_thing and its
parent_things and its child_things in one collection. It doesn't
sound like that's the intention here.

Use the :has_many x, :through=>y semantics. In this case you would
add:

has_many :child_things, :through=>:parent_things

to the GrandParentClass. With that you can refer to
grand_parent_thing.child_things and get all the children.

HTH,
AndyV

I think acts_as_nested_set will add more functionality than you want.
Its intent is to provide the full tree, grand_parent_thing and its
parent_things and its child_things in one collection. It doesn't
sound like that's the intention here.

It gives you a full subtree. The OP wanted to "get all of the
child_things that a grandparent_thing has" , which if you look at his
model structure, means that, given a grandparent, he wants to get all
its grandchildren. And acts_as_nested_set will do exactly that.

Use the :has_many x, :through=>y semantics. In this case you would
add:

has_many :child_things, :through=>:parent_things

to the GrandParentClass. With that you can refer to
grand_parent_thing.child_things and get all the children.

Yes, this will work too. I *think* acts_as_nested_set would be more
efficient though, because it is optimized for retrieval--no joins are
needed.

-- Mark.

Mark Thomas wrote:

  

I think acts_as_nested_set will add more functionality than you want.
Its intent is to provide the full tree, grand_parent_thing and its
parent_things and its child_things in one collection. It doesn't
sound like that's the intention here.
    
It gives you a full subtree. The OP wanted to "get all of the
child_things that a grandparent_thing has" , which if you look at his
model structure, means that, given a grandparent, he wants to get all
its grandchildren. And acts_as_nested_set will do exactly that.

Doesn't acts_as_nested_set's all_children() method return all
descendants of a given node? Meaning that you would get all
parent_things and child_things in the same query?

Also, according to the docs
(http://api.rubyonrails.org/classes/ActiveRecord/Acts/NestedSet/ClassMethods.html#M000652),
acts_as_nested_set requires a full table rewrite to insert or remove a
node.