Simon Cooper
Simon Cooper

Reputation: 1594

Trouble displaying individual images from array (Rails active storage)

I'm sure this should be simple and I'm overlooking something daft.

Rails 6.1.1 Ruby 3.0.0

I'm using active storage to attach multiple 'photos' to my Articles model.

In Articles 'show.html.erb' I want to place the photos in a number of different places in the article, not looping all of them in a row in the same place.

show.html.erb

<% @first2photos.each do |article| %>
    <%= image_tag(article.photos) %>
  <% end %>

articles.controller.erb

  def show
    @first2photos = Article.order("created_at DESC").first(2)
  end

This gives the following error: Can't resolve image into URL: undefined method `to_model' for #<ActiveStorage::Attached::Many:0x00007fdbbfa852a8 @name="photos", @record=#<Article id: 1, title: "This is the first post", snippet: "Hopefully this will also attach a couple of photos", body: "Nullam ac odio eget mauris accumsan malesuada. Nul...", created_at: "2021-01-30 20:50:31.766713000 +0000", updated_at: "2021-01-30 21:04:09.424224000 +0000">> Did you mean? to_yaml

If I loop on 'photo's with:

<% @first2photos.each do |photos| %>
    <%= image_tag(@article.photos) %>
  <% end %>

I still get the following error:

Can't resolve image into URL: undefined method `to_model'...

Changing that to:

<% @first2photos.each do |photos| %>
    <%= image_tag(photos) %>
  <% end %>

The page now loads, but shows a broken image icon, with no error. Checking the log in Terminal, I'm not sure I can see where it's attempting to access the photo.

Started GET "/articles/1" for ::1 at 2021-01-31 20:56:58 +0000
Processing by ArticlesController#show as HTML
  Parameters: {"id"=>"1"}
  Article Load (2.9ms)  SELECT "articles".* FROM "articles" WHERE "articles"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/articles_controller.rb:64:in `set_article'
  Article Load (1.4ms)  SELECT "articles".* FROM "articles" ORDER BY created_at DESC LIMIT $1  [["LIMIT", 2]]
  ↳ app/controllers/articles_controller.rb:11:in `show'
  Rendering layout layouts/application.html.erb
  Rendering articles/show.html.erb within layouts/application
  Rendered articles/show.html.erb within layouts/application (Duration: 0.4ms | Allocations: 155)
[Webpacker] Everything's up-to-date. Nothing to do
  Rendered layout layouts/application.html.erb (Duration: 8.6ms | Allocations: 4208)
Completed 200 OK in 20ms (Views: 9.3ms | ActiveRecord: 4.4ms | Allocations: 6022)

Upvotes: 0

Views: 335

Answers (1)

arieljuod
arieljuod

Reputation: 15838

You need to loop over the photos collection to use image_tag for each photo.

<% @first2photos.each do |article| %>
  <% article.photos.each do |photo|
    <%= image_tag(photo) %>
  <% end %>
<% end %>

If you want to show only one image per article then:

<% @first2photos.each do |article| %>
  <%= image_tag(article.photos.first) %>
<% end %>

I would change the name first2photos to first2articles to make it less confusing too.

Upvotes: 1

Related Questions