mpora
mpora

Reputation: 1479

rails nested model navigation

I have an app with three models:

Client

has_many :papers

Paper

has_many :pages
belongs_to :client

Page

belongs_to :paper

I can do this in code: @paper.client.name

But I am unable to do @paper.page.name NoMethodError is produced

What I am doing wrong? These are all nested models, where Client is at high level.

Upvotes: 0

Views: 66

Answers (2)

Cade
Cade

Reputation: 3181

While Marc's explanation is absolutely correct, using a for loop in Ruby for this purpose (and just about any purpose really) is in not at all idiomatic. The usage of each is far more common:

@paper.pages.each { |page| puts page.name }

If you just want the list of names, you can use map:

@paper.pages.map(&:name)

map will execute a block for each item in the collection and return an array of the results. The &:name is a shorthand for:

@paper.pages.map { |page| page.name }

Enumerable plays a big part in idiomatic Ruby.

And, not to be too confusing, there's also pluck in Rails for just getting an array of a single attribute, but you should only use it if it's the only thing you want from the collection:

@paper.pages.pluck(:name)

Upvotes: 1

Marc Baumbach
Marc Baumbach

Reputation: 10473

Your Paper object has many pages, so there's no page method. If you want to get the names of all the pages belonging to a Paper object, you'll need to iterate over the pages association:

for page in @paper.pages
    puts page.name
end

Upvotes: 1

Related Questions