开发者

Rails grandchildren objects with :has_many, :through

开发者 https://www.devze.com 2023-04-04 19:49 出处:网络
I have a schema structured as follows: class Foo < ActiveRecord::Base has_many :foo_bars has_many :foo_bar_bazs, :through => :foo_bars

I have a schema structured as follows:

class Foo < ActiveRecord::Base
  has_many :foo_bars
  has_many :foo_bar_bazs, :through => :foo_bars
end


class FooBar < ActiveRecord::Base
  has_many :foo_bars
  belongs_to :foo_bar
end

Class F开发者_运维问答ooBarBaz < ActiveRecord::Base
  belongs_to :foo_bar
end

I'm trying to do a select on the Foo model - like Foo.find(:all). Both FooBar and FooBarBaz have the correct foreign key column in the database (foo_id and foo_bar_id, respectively). So how do I access the child and grandchild objects when I access the grandparent object (Foo)?

In the end I need to be iterate through the Foo objects, then through the Foobar objects, then through the FoobarBaz objects, in three nested loops.


First, I'd revise the syntax to match convention:

class Foo < ActiveRecord::Base
  has_many :foo_bars
  has_many :foo_bar_bazs, :through => :foo_bars
end


class FooBar < ActiveRecord::Base
  has_many :foo_bar_bazs
  belongs_to :foo_bar
end

Class FooBarBaz < ActiveRecord::Base
  belongs_to :pc_scene_item
end

Now that we have the objects:

Foo.find(:all, :include => [:foo_bars, :foo_bar_bazs])

Now, :through can be avoided, and you can do:

foos = Foo.find(:all, :include => [{:foo_bars => [:foo_bar_bazs]}])

To get all children:

children = foos.collect{|f| f.foo_bars}.flatten.uniq

To get all grandchildren:

grandchildren = foos.collect{|f| f.foo_bars.collect{|b| b.foo_bar_bazs}}.flatten.uniq


You shouldn't use camel case to name your associations, but snake case:

class Foo < ActiveRecord::Base
  has_many :foo_bars
  has_many :foo_bar_bazs, :through => :foo_bars
end

class FooBar < ActiveRecord::Base
  has_many :foo_bar_bazs
  belongs_to :foo
end

class FooBarBaz < ActiveRecord::Base
  belongs_to :foo_bar
end


I think there is a mistake on your FooBar model. I think you intended to say that it belongs_to Foo, not FooBar (currently you have FooBar belong to itself).

Assuming you have all the other data and relationship in place, you should be able to call it foo.foo_bar

0

精彩评论

暂无评论...
验证码 换一张
取 消