Joel Grannas
Joel Grannas

Reputation: 2016

ActiveRecord: Has_many inside another has_many - with rails3

So I am setting up a system of pages and apps, and app content. Where a page has_many :app_instances, and app_instances has_many :app_contents.

I have models: page, app, app_instance, app_content

In my models:

class Page < ActiveRecord::Base
  has_many :app_instances
end

class App < ActiveRecord::Base
  belongs_to :page
end

class AppInstance < ActiveRecord::Base
  belongs_to :page
  belongs_to :app
  has_many :app_contents
end

class AppContent < ActiveRecord::Base
  belongs_to :app_instance
  belongs_to :app
end

I'd like to have one object, where all the contents are under the individual contents live under the app instance... but is there a way to do this?

I setup this in one of my controllers:

@page = Page.includes(:app_instances).find(params[:id])

I can successfully debug @page.app_instances, but soon as I say @page.app_instances.app_contents i get an error. I am guessing this is just because i am missing the include within the include, but not sure how i write that, or even if that is "good practice"

I know i could probably do:

has_many :app_contents, :through => :app_instances

but id rather have the object organized with the instance holding the contents (that makes sense, right?)... so i could loop through all the instances, and print out the contents of the instance

Does my DB architecture make sense? or am I going at this the wrong way

Joel

Upvotes: 2

Views: 147

Answers (1)

Rahul garg
Rahul garg

Reputation: 9362

You can include nested using:

Page.includes(:app_instances=>[:app_contents])

But main reason you are getting an error is because, in @page.app_instances.app_contents page.app_instances doesn't have any app_contents. You would be looking for an union of app_contents of all app_instances of @page

So it can be done via:

@page.app_instances.app_contents.each{|ai| (list || =[]) << ai.app_contents}
list.flatten!

OR

define page has many app_contents through app_instances relationship in your model.

The first case would run query for each app_instances , however with using includes as I mentioned earlier that would result in single query. The second case would result in a single join query joining app_contents, app_instances table

Upvotes: 1

Related Questions