1

I am working in Ruby on Rails 6.0 and up with Shrine and trying to get the first photo of my images to be the cover image of my Album page. I am working from the Rails-Shrine-Example here:

https://github.com/erikdahlstrand/shrine-rails-example

My goal is to show the first photo from the uploaded photos as the cover photo and not the cover_photo in the album table. Is this possible?

My code for the album cover is:

<% @albums.each do |album| %>
  <tr>
    <td scope="row"><%= image_tag album.cover_photo_url(:small), size: "200x200", class: "img-thumbnail" %></td>
    <td scope="row"><%= album.name %></td>
    <td scope="row"><%= link_to "Edit", album, class: "btn btn-default" %> <%= link_to "Show", album, class: "btn btn-default" %></td>
  </tr>
<% end %>

Then inside my album I was able to pull the first photo from the album with

<% @album.photo.each do |photo| %>
   <div class="col-lg-3 col-md-4 col-6">
      <%= image_tag photo.image.derivation_url(:thumbnail, 300, 300).to_s, :class => "img-fluid img-thumbnail" %>
   </div>
<% end %>

So that I try to explain it all, my db has an album table with the title and cover photo and there is another table for photos.

How can I tell it to select for each album show first image from that album's photo table?

*UPDATE I was able to put this script up and it works to some degree except the each loop shows the first photo in my photo table the number of times equal to the number of photos uploaded. I know its my loop.

   <% @albums.each do |album| %>
      <tr>
        <td scope="row">
          <% album.photos.each do |photo| %>
            <%= image_tag album.photos.first.image.derivation_url(:thumbnail, 300, 300), :class => "img-fluid img-thumbnail" %>
          <% end %>
      </td>
        <td scope="row"><%= image_tag album.cover_photo_url(:small), size: "200x200", class: "img-thumbnail" %></td>
        <td scope="row"><%= album.name %></td>
        <td scope="row"><%= link_to "Edit", album, class: "btn btn-default" %> <%= link_to "Show", album, class: "btn btn-default" %></td>
      </tr>
    <% end %>

Photo Model

    class Photo < ActiveRecord::Base
  include ImageUploader::Attachment(:image)  # ImageUploader will attach and manage `image`
end

Album Model

    class Album < ApplicationRecord
  has_many :photos, dependent: :destroy
  accepts_nested_attributes_for :photos, allow_destroy: true

  include ImageUploader::Attachment(:cover_photo)  # ImageUploader will attach and manage `cover_photo`

  validates_presence_of :name, :cover_photo  # Normal model validations - optional
end

As Lurker had shared that I was also pulling from albums that didn't have photos attached. I am not sure what to do to fix the string. I know some image_tags use the if present? or something but I cannot add it to this without errors.

4
  • Just get rid of the loop. Your loop contents don't reference the photo loop variable, so it's not needed. Just do this once, not for each photo: <%= image_tag album.photos.first.image.derivation_url(:thumbnail, 300, 300), :class => "img-fluid img-thumbnail" %> already shows the first photo of the album. Commented Jun 26, 2020 at 15:06
  • Removing the loop throws an error of undefined method `image' for nil:NilClass Commented Jun 26, 2020 at 15:09
  • Interesting. I'm not sure how that's possible since the expression doesn't use any variable that the looping provides. Having the loop repeats the same expression multiple times. Removing the loop should execute the expression just once. So if the error occurs without the loop, I would expect it with the loop. That error means that album.photos.first was nil, and that expression doesn't depend upon photo. Do you have any albums with no photos? Can you show your Photo and Album models (particular the part showing how they are related)? Commented Jun 26, 2020 at 15:16
  • 1
    @lurker You are right! there was an album that didn't have photos. Once I added photos to that album it displayed correctly. How do I tell it to ignore if not present. I have tried doing the present? addon I have seen on other image_tag parts, but I don't know the proper order. I will share the models in the original post. Commented Jun 26, 2020 at 15:29

1 Answer 1

1

Ok so I think I figured it out. With the string of conditions on the photo I cannot do a simple if present? argument. I needed to create a if else statement. So here is what I found works for me.

<% if  album.photos.present? %>
      <%= image_tag album.photos.first.image.derivation_url(:thumbnail, 300, 300).to_s %> 
  <% else %>
     <%= image_tag 'image.jpg' %>
  <% end %>
Sign up to request clarification or add additional context in comments.

2 Comments

There are probably a few different ways to do this check in Ruby, but your approach is good and clear. By the way, you are allowed to "accept" your own answer. :)
apparently I have to wait 2 days... so it says. Thank you for the help. All the answers really helped me work it out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.