Michael Feihstel
Michael Feihstel

Reputation: 1050

Rails: How to retrieve an attribute from a related model?

I seem to be stuck with a problem that probably should be more obvious to me: How can I get certain attributes from a related model to show in a view.

In my application there are these 2 models:

products
product_images

I'm writing this while I'm on the go and don't have the exact code available. However I created the necessary associations, so that a product has_many product_images and a product_image belongs_to a product. The image model has an url, a default (boolean) flag and of course the product_id.

In the product index view I'd like to display the default image for that product. For the sake of simplicity though let's just assume I'm fine with showing the first picture - conditions should be easy to introduce once this works.

So in my products index view there's something like this (again, just from memory):

@products.each do |p|
    <h3><%= p.name %></h3>
    <%= image_tag p.product_images.first.url %>
    <p><%= p.description %></p>
end

While the description and name of the product alone display just fine as soon as I include the image_tag my view breaks with a NoMethodError stating that url is an undefined method in Class Nil. To keep it even simpler I got rid of the image_tag and just wanted to see the url printed in a paragraph - the problem remains of course. If I just try to get p.product_images.first the view prints what I assume is some sort of ID for the object/model just fine, which tells me that the association itself is ok. So why does Rails think that the url attribute should be a method?

I also checked back with the rails console to see if this is the correct syntax to retrieve a related attribute. Like so (again, from memory - syntax errors possible):

p = Product.first
=> [successful - shows the first product]
p.product_images.first
=> [successful - shows the first image model]
p.product_images.first.url
=> [successful - shows me the single attribute, the url to the image]

As you can tell by now I'm very new to this and your help is very much appreciated. Of course I read the Rails documentation, however the Active Record Query Guide mostly focuses on getting data from the current model and I wasn't able to find what I'm obviously missing in my sample app.

Why does this work in the console but not in the view?

Upvotes: 1

Views: 202

Answers (1)

pungoyal
pungoyal

Reputation: 1798

It is probably because one of your Product does not have any ProductImage.

You can correct this by adding a method in your ProductsHelper like so:

def product_image(product)
    return if product.product_images.blank?

    image_url = product.product_images.first.url
    return if image_url.nil?

    image_tag(image_url).html_safe
end

And then call it from your view like so:

@products.each do |p|
    <h3><%= p.name %></h3>
    <%= product_image(p) %>
    <p><%= p.description %></p>
end

Upvotes: 1

Related Questions