request active storage image show only one not all images - ruby-on-rails

As Rookie Rails, i am able to get all images to display on the html.erb as using model as has_many_attached :images
but i have tried many different way like this code below
<div class="row">
<div class="col-md-12">
<% if #tool.images.attached? %>
<% #tool.images.each do |image| %>
<div class="img-fluid <%= 'active' if image.id == #images[0].id %>">
<%= link_to image_tag(image), image %>
</div>
<% end %>
<% end %>
</div>
</div>
but didn't show one image but only a few images as I am trying to fix this
image.id == #images[0].id
this code is dont display one image, do you know where i can use this code into this as i have tried many way but all failed
if i use this code
<!-- Image -->
<div class="row">
<div class="col-md-12">
<% if #tool.images.attached? %>
<% #tool.images.each do |image| %>
<%= link_to image_tag(image, class:"tools-gallery"), image %>
<% end %>
<% end %>
</div>
</div>
<br/>
it show fine and able to get displayed
but I don't want two images or more, it ok for the gallery but not this pages as it need show one image.
and the controller.rb
def show
#images = #tool.images
end

<div class="row">
<div class="col-md-12">
<%= image_tag #tool.images.first if #tool.images.attached? %>
</div>
</div>

Related

Images on Active Storage not displayed on the ERB page but another ERB page are displayed

I am bit lost somewhere, as I have build gallery with active storage and it's fine and I am able to see images and upload the images
Here is a screenshot
But one problem, as I try to create a new page for listing page, I am trying to get images on thumb page
<div class="row">
<div class="col-md-3">
<ul class="sidebar-list">
<li class="sidebar-item"><%= link_to "Your tools Listings", tools_path, class: "sidebar-link active" %></li>
</ul>
</div>
<div class="col-md-9">
<div class="panel panel-default">
<div class="panel-heading">
Listings
</div>
<div class="panel-body">
<% #tools.each do |tool| %>
<div class="row">
<div class="col-md-2">
<%= tool.images %>
</div>
<div class="col-md-7">
<h4><%= tool.listing_name %></h4>
</div>
<div class="col-md-3 right">
<%= link_to "Update", listing_tool_path(tool), class: "btn btn-black-free-account" %>
</div>
</div>
<hr/>
<% end %>
</div>
</div>
</div>
</div>
it should be fine as long it shows a text-based of images see screenshot below
So I need to change these images as I am using the same method as the first screenshot, as the code below
<% if #tool.images.attached? %>
<div class="panel panel-default">
<div class="panel-heading">
Photo Display
</div>
<br>
<div class="row">
<% #tool.images.each do |image| %>
<div class="col-md-4">
<div class="panel panel-default tools-gallery-panel">
<div class="panel-heading preview ">
<%= link_to image_tag(image, class:"img-thumbnail tools-gallery"), image %>
</div>
<div class="panel-body">
<span class="pull-right">
<i class="fa fa-trash-o fa-lg" aria-hidden="true"></i>
<%= link_to "Remove", delete_image_attachment_tool_path(image), method: :delete, data: {confirm: "Are you sure?"} %>
</span>
</div>
</div>
</div>
<% end %>
<% end %>
</div>
so I copied
<%= link_to image_tag(image, class:"img-thumbnail tools-gallery"), image %>
this to new listing pages stuff
so I modify the listing page
<% #tools.each do |tool| %>
<div class="row">
<div class="col-md-2">
<%= tool.images %>
<%= link_to image_tag(tool.images, class:"thumbnail"), images %>
</div>
<div class="col-md-7">
<h4><%= tool.listing_name %></h4>
</div>
<div class="col-md-3 right">
<%= link_to "Update", listing_tool_path(tool), class: "btn btn-black-free-account" %>
</div>
</div>
<hr/>
<% end %>
and all I got an error
even I have tried this
<%= link_to image_tag(tool, class:"thumbnail"), images %>
Tool.rb
class Tool < ApplicationRecord
belongs_to :user
has_many_attached :images
validates :tool_type, presence: true
validates :power_type, presence: true
validates :accessories, presence: true
validates :brand, presence: true
validates :price, presence: true
end
and I get same error, Any suggest would be great
In your model you have has_many_attached :images
tool.images regardless the number of images will alway return an ActiveSTorage::Attached::Many which is an Enumerable so you will have to loop through it to get each image, in the loop each image will be an ActiveStorage::Blob, to use image_tag you will need a url for the image, to get the url from the blob you would use url_for(image).
Here is an example:
<% tool.images.each do |image| %>
<%= image_tag(url_for(image), class: 'some-class') %>
<% end %>
In your case you wanted the image to be a link, that is easy to do as well you just have to pass the correct information to link_to. You can do this in multiple ways this is the way I think is the easiest to read.
With a link:
<% tool.images.each do |image| %>
<%= link_to "Path to Tool as string" do %>
<%= image_tag(url_for(image), class: 'some-class') %>
<% end %>
<% end %>
This is the API for link_to:
link_to name, options = {}, html_options = nil
This is the API for image_tag:
image_tag source, options={}
Lastly, you're seeing this error:
Can't resolve image into URL: undefined `to_model` for #<ActiveStorage::Attached::Many>
You are getting this error because you're try to create an image tag with a single image not a collection of "many".
Look at your original working code (superfluous HTML stripped away):
<% #tool.images.each do |image| %>
<%= link_to image_tag(image, class:"img-thumbnail tools-gallery"), image %>
<% end %>
Notice how you are looping through all the images? That is because a #tool has many images. It is an array of images. Inside the link_to block, you're defining an image_tag properly with a single image as the reference. Now lets look at your erroneous code:
<% #tools.each do |tool| %>
<%= tool.images %>
<%= image_tag(tool.images, class:"thumbnail"), images %>
<% end %>
This is weird. You're calling this:
<%= tool.images %>
Which just displays an instance of #<ActiveStorage::Attached::Many> and you're calling this:
<%= link_to image_tag(tool.images, class:"thumbnail"), images %>
Which just attempts (and fails) to link an array of images to a single image_tag instance which we know is invalid thanks to the api. You likely want to do this:
<% #tools.each do |tool| %>
<%= tool.images.each |image| %>
<%= image_tag(image, class:"thumbnail"), image %>
<% end %>
<% end %>

I'm trying to render two columns of information in my rails app

So, I have an app that is trying render 2 (or maybe more if needed) columns using a loop. It does one column and looks pretty good, but I want the option of 2 or even more. I know about "in_groups.of()", but I can't quite figure it out to work with my
<% #vendors.each do |vendor| %>
<%= link_to vendor do %>
<div class="row">
<div class="col-md-6">
<div class="card-container">
<div class="col-md-6">
<div class="card">
<%= image_tag attachment_url(vendor, :background_image), class: 'card-img-top' %>
<div class="card-block">
<h4 class="card-title"><%= vendor.Company %>. </h4>
<p class="card-text"><%= vendor.Description.html_safe.first(25) %></p>
<div class="card-standing"><strong><%= vendor.FinancialStanding %></strong></div>
</div>
</div>
</div>
</div>
</div>
</div>
<% end %>
<% end %>
Not sure why you needed this, because everything can be managed with css and html. But you can make changes like this:
<% #vendors.to_a.in_groups_of(2).each do |vendor| %> # #vendors.to_a cover AR to array
<% vendor.each do |v| %> # becuase vendor is array here.
..........your code..............
<% end %>
<% end %>

Ruby on Rails View Rendering DB Info On Page

I am working on a project and currently working on one of the views which is a page of different categories. Everything is rendering correctly however it's also putting the db info in the page.
Here is the code of my view
<div class="categories">
<div class="container blurbs">
<div class="cards row">
<%= #categories.each do |c| %>
<div class="card col-xs-4" %>
<%= image_tag c.image, :class => "cat" %>
<h4 class="title"><%= c.title %></h4>
</div>
<% end %>
</div>
</div>
</div>
Here is a link to a
screenshot of rendered page
Yes, fix is:
<div class="categories">
<div class="container blurbs">
<div class="cards row">
<% #categories.each do |c| %>
<div class="card col-xs-4" %>
<%= image_tag c.image, :class => "cat" %>
<h4 class="title"><%= c.title %></h4>
</div>
<% end %>
</div>
</div>
</div>
Look I removed = from this <%=.. In the below line :
<% #categories.each do |c| %>
#each method returns the collection after it completed its iterations. And due to this <%=, the return value of each which is #categories printed back. But if you use <%.. only, all above things will happen, but it wouldn't print back the object #categories.
when you use the tags <%= ... %> whatever is within the tags gets displayed on the page. In your current view you have
<%= #categories.each do |c| %>
<div class="card col-xs-4" %>
<%= image_tag c.image, :class => "cat" %>
<h4 class="title"><%= c.title %></h4>
</div>
<% end %>
Which displays the entirety of whatever the loop returns which is where you're getting the display. Change the tags to be <% #categories.each do |c| %> and you'll be good to go.

Rails passing attributes to nested modals with foundation

I have the following code. In the first modal that comes up I'm listing all of the user's images. When they click on one of the images it triggers the second modal and I want the id of the image to be available to me. But it's always coming back as the id of the last image.
<div id="firstModal" class="reveal-modal" data-reveal>
<% if signed_in? %>
<h4>Your Images</h4>
<div class="dashboard-panel">
<% #assets.each do |asset| %>
<%= image_tag asset.file_name.url(:dashboard).to_s %>
<%= asset.id %>
<% end %>
</div>
<% else %>
You don't have any images.
<% end %>
<a class="close-reveal-modal">×</a>
</div>
<div id="secondModal" class="reveal-modal" data-reveal>
<h2>This is a second modal.</h2>
<p>Asset id is <%= #selected_asset.inspect %></p>
<a class="close-reveal-modal">×</a>
</div>
I think there is something wrong with my structure but I can't figure it out :(
The html of the second modal is only generated once. The value of #selected_asset will be the id of the last asset in the loop. One option is to generate a separate modal for each image, something like this:
<% #assets.each do |asset| %>
<a href="#" data-reveal-id="secondModal-<%= asset.id %>Click</a>
<div id="secondModal-<%= asset.id %>" class="reveal-modal" data-reveal>
<h2>This is a second modal.</h2>
<p>Asset id is <%= asset.id %></p>
<a class="close-reveal-modal">×</a>
</div>
<% end %>
Note the inclusion of asset.id in the id of the modal so they are all unique

How to put images into an array Ruby on Rails

I have a Ruby on Rails app that allows a user to save up to 6 images that can then be viewed in a carousel.
The images are saved as strings as image, image_2, image_3, image_4, image_5, image_6.
I want to be able to write a 'for' loop to display all of the images in my carousel.
What is the best method of combining all of these image strings into an array so that they can then be looped through and outputted by the carousel?
Further Details
I am currently calling the images like below which works but isn't particularly DRY.
<div style="position:relative">
<div id="home-carousel" class="carousel">
<div class="carousel-inner">
<div class="item active">
<%= image_tag #place.image %>
</div>
<% if #place.image_2.present? %>
<div class="item">
<%= image_tag #place.image_2 %>
</div>
<% end %>
<% if #place.image_3.present? %>
<div class="item">
<%= image_tag #place.image_3 %>
</div>
<% end %>
<% if #place.image_4.present? %>
<div class="item">
<%= image_tag #place.image_4 %>
</div>
<% end %>
<% if #place.image_5.present? %>
<div class="item">
<%= image_tag #place.image_5 %>
</div>
<% end %>
<% if #place.image_6.present? %>
<div class="item">
<%= image_tag #place.image_6 %>
</div>
<% end %>
</div>
</div>
</div>
I would like to be able to turn what I have below into a simple for loop that will go through each of the 6 image objects and return the ones that are there. Something more like this:
<div style="position:relative">
<div id="home-carousel" class="carousel">
<div class="carousel-inner">
<% #place.images.each do |image| %>
<div class="item">
<%= image_tag image %>
</div>
<% end %>
</div>
</div>
</div>
The simple solution is to add a helper. So in helpers/places_helper.rb write
module PlacesHelper
def get_carrousel_images(place)
[
#place.image_1,
#place.image_2,
#place.image_3,
#place.image_4,
#place.image_5,
#place.image_6
].select {|img| img.present? }
end
and then you can write the following in your view:
<div style="position:relative">
<div id="home-carousel" class="carousel">
<div class="carousel-inner">
<% get_carrousel_images(#place).each do |image| %>
<div class="item">
<%= image_tag image %>
</div>
<% end %>
</div>
</div>
</div>
Now having the 6 image_x fields for place looks a bit smelly, so I would prefer a nested model instead as Rich Peck proposes, although I understand having the 6 fields is easier to start with.
Images
It will all depend on how you've set up the images in the db, and how you'd like to show them in the view
If you have the images in the User model, you could call them like this:
app/controllers/users_controller.rb
Class UsersController < ApplicationController
def show
#user = User.find params[:id]
#images = #user.images
end
end
This is obviously very generalised - I would recommend you post some context to your question, so we know what you're asking specifically
--
Paperclip
If you're using Paperclip or Carrierwave, you'll basically have the images attached to various objects in your database. For example, you'll have the following:
#app/models/image.rb
Class Image < ActiveRecord::Base
has_attached_file :attachment
end
This allows you to call:
#images = Image.all
#images.each do |image|
image.attachment.url #-> image URL
end
This is the standard way to handle images / attachments in Rails, as it ties directly into ActiveRecord. Returning an array of image paths would therefore be a case of calling Model.all or Model.where

Resources