How to access an instance variables id in the view - ruby-on-rails

I'm using carrierwave to upload photos into my app, the photos have a 'belongs_to' relationship with each location, and the location has a 'has_many' relationship to the photos. Im my show page where the photos for the locations are uploaded they display as normal through a loop. However, in my index page I'm looping through my locations and want to display a photo for that location. The photos have the correct location_id, I'm just not sure on the syntax in the view to access that locations photo. What I would like to do is display one of the photos that correlates to a specific location, something like: #photo(location.id.last). Any help would be much appreciated, thanks in advance.
View
<div class="row">
<!-- featured listings gallery -->
<% #locations.each do |location| %>
<% if location.featured == "true" %>
<div class="col-md-4 col-xs-6">
<div class="thumbnail">
<div class="overlay">
<%= image_tag #photos, :size => '400x300', :class => 'img-responsive' %>
<div class="effect">
<div class="overlay-header">
<%= location.name %>
</div>
<div class="location-link">
<%= link_to "View Building", location_path(location) %>
</div>
</div>
</div>
<h3 class="display-box-caption">
<%= truncate(location.description, length: 100) %><%= link_to 'More', location_path(location), :class => 'more-info' %>
</h3>
</div>
<div class="col-md-12 property-link-container">
<%= link_to "View Building", location_path(location), :class=>"property-link" %>
</div>
</div>
<% end %>
<% end %>
</div>
controller
class PagesController < ApplicationController
def index
#locations = Location.all
#photos = Photo.all
end
def about
end
def faqs
end
def blog
end
def whats_included
end
end

Accessing photo with the help of association:
location.photos.last.photo.url
HTML
<div class="row">
<!-- featured listings gallery -->
<% #locations.each do |location| %>
<% if location.featured == "true" %>
<div class="col-md-4 col-xs-6">
<div class="thumbnail">
<div class="overlay">
<!-- changing #photos to location.photos.last -->
<% if location.photos.any? and location.photos.photo.present? %>
<%= image_tag location.photos.last.photo.url, :size => '400x300', :class => 'img-responsive' %>
<% end %>
<div class="effect">
<div class="overlay-header">
<%= location.name %>
</div>
<div class="location-link">
<%= link_to "View Building", location_path(location) %>
</div>
</div>
</div>
<h3 class="display-box-caption">
<%= truncate(location.description, length: 100) %><%= link_to 'More', location_path(location), :class => 'more-info' %>
</h3>
</div>
<div class="col-md-12 property-link-container">
<%= link_to "View Building", location_path(location), :class=>"property-link" %>
</div>
</div>
<% end %>
<% end %>
</div>
Controller:
def index
#locations = Location.all
# no need to fetch photos now
# #photos = Photo.all
end
Photo Model
class Photo < ActiveRecord::Base
belongs_to :location
mount_uploader :photo, PhotoUploader
end

I see Sahil's post helped. Add .includes(:photos), to load Queries faster. In the future, will be super useful.
def index
#locations = Location.includes(:photos).all
end

Related

Loop through posts that is promote

How to loop through post that are on promoted. I have a method in my post model that I can access. How would I call it in this instance. For example here are my methods my post model.
class Post < ApplicationRecord
def promoted?
subscriptions.present?
end
def self.promoted_posts
Post.joins(:subscriptions).where(:subscriptions => {:is_active => true})
end
def self.not_promoted_posts
Post.left_outer_joins(:subscriptions).where(:subscriptions => {:post_id => nil})
end
def self.ordered_posts
Post.promoted_posts + Post.not_promoted_posts
end
end
Here is my view. I would like to loop through all the posts that are promoted which is the method "def promoted?" in my model
<% #posts.take(6).each do |post| %>
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-4">
<div class="featured-box">
<figure>
<%= link_to image_tag(post.images.first, class: 'img-fluid'), post %>
</figure>
<div class="feature-content">
<div class="product">
<p><%= post.category.name %> / <%= post.subcategory.name %></p>
</div>
<h4><%= link_to post.title, post %></h4>
<ul class="address">
<li>
Ad#: <%= post.ad_number %>
</li>
<li>
posted <%= time_ago_in_words(post.created_at) %> ago
</li>
<li>
<%= post.state%> , <%= post.city.downcase %>
</li>
</ul>
<div class="listing-bottom">
<h3 class="price float-left">$<%= post.price%></h3>
<%= link_to 'Feature Ad', post, class: 'btn-verified float-right', style: 'color: red;' %>
</div>
</div>
</div>
</div>
<% end %>
If you are desperately in need of using the promoted, you can try
Post.all.find_all(&:promoted?)
which is short notation of
Post.all.find_all do |post|
post.promoted?
end
which is kinda n+1 query and opting it while you can just use
Post.joins :subscriptions
is a fail.

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 %>

Advanced Search Box Not Showing Results or Connecting to the Show View

I am fairly new to Ruby on Rails, and I am trying to implement an advanced search. The advanced search is to search for books and their categories.
Please let me know if you need additional information.
I have implemented the advanced search form view, new view and show view.
But when I try to search for books, it doesn't display the search results neither doesn't render the show view for searches. It rather renders a new view page for Advanced Search.
Here is my Searches Controller Code
class SearchesController < ApplicationController
def new
#search = Search.new
end
def create
#search = Search.create(search_params)
redirect_to #search
end
def show
#search = Search.find(params[:id])
end
private
def search_params
params.require(:search).permit(:keywords, :category)
end
end
Here is my Search Model Code
class Search < ApplicationRecord
def search_books
books = Book.all
books = books.where(["name LIKE ?","%#{keywords}%"]) if
keywords.present?
books = books.where(["category LIKE ?",category]) if
category.present?
return books
end
end
Here is my Searches _form.html.erb Code
<%= form_with(model: search, local: true) do |form| %>
<div class="form-group">
<%= form.text_field :keywords, {placeholder: 'Keywords',
:class => 'form-control pb_height-50 reverse'} %>
</div>
<div class="form-group">
<%= form.text_field :category, {placeholder: 'Category',
:class => 'form-control pb_height-50 reverse'} %>
</div>
<div class="form-group">
<%= form.submit :class => 'btn btn-primary btn-lg btn-block
pb_btn-pill btn-shadow-blue', value: 'Search'%>
</div>
<% end %>
Here is my Searches new.html.erb Code
<% content_for :title, "New Search" %>
<section class="pb_cover_v3 overflow-hidden cover-bg-indigo cover-
bg-opacity text-left pb_gradient_v1 pb_slant-light menu-section"
id="section-home">
</section>
<section class="pb_section bg-light pb_slant-white pb_pb-250"
id="section-features">
<div class="container">
<div class="row align-items-center justify-content-center">
<div class="col-md-12 relative align-self-center">
<form action="/search" class="bg-white rounded pb_form_v1">
<h2 class="mb-4 mt-0 text-center">Advanced Search</h2>
<hr>
<%= render 'form', search: #search %>
<hr>
<%= link_to 'Back', books_path %>
</form>
</div>
</div>
</div>
</section>
Here is my Searches show.html.erb Code
<% content_for :title, "Search Result" %>
<section class="pb_cover_v3 overflow-hidden cover-bg-indigo
cover-bg-opacity text-left pb_gradient_v1 pb_slant-light menu-
section" id="section-home">
</section>
<section class="pb_section pb_slant-white pb_pb-250" id="section-
features">
<div class="container">
<div class="row titlerow">
<h1><%= Search Result %></h1>
<p><%= link_to 'Back', new_search_path %></p>
<% if #search.search_books.empty? %>
<p>No Records Found</p>
<% else%>
<% #search.search_books.each do |c| %>
<br>
<div class="div">
<h1><%= c.name %></h1>
<p>Category: <%=c.category %></p>
</div>
<% end %>
<% end %>
</div>
</div>
</section>
I need some assistance on how my search results can be displayed on the show view of the searches, instead of the Advanced Search page re-rendering the a new search page each time I click the Search Button of the Advanced Search. I need a way to connect the Show View of the Advanced Search to the New Advanced Search Page, so that it can display search results.
Thank you.
I was able to fix it.
On the new.html.erb
<section class="pb_section bg-light pb_slant-white pb_pb-250" id="section-features">
<div class="container">
<div class="row align-items-center justify-content-center">
<div class="col-md-12 relative align-self-center">
<form action="/search" class="bg-white rounded pb_form_v1">
<h2 class="mb-4 mt-0 text-center">Advanced Search</h2>
<hr>
<%= render 'form', search: #search %>
<hr>
<%= link_to 'Back', books_path %>
</form>
</div>
</div>
</div>
</section>
I simply changed the form tag to to a div tag, and also removed the action attribute from the form tag.
I have learnt a lot in the process.
That's all.
I hope this helps

Create a link from a div - Ruby on Rails

Currently I have a text link within the div that links correctly <%= link_to 'Show', profile %>. I have read that the below is the proper way to turn a div into a link
<%= link_to root_path do %>
<div>Hey!</div>
<% end %>
Though when I apply that to my block it gives me a undefined local variable or method 'profile'
<%= link_to profile do %>
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
<%= link_to 'Show', profile %>
</div>
</div>
<% end %>
</div>
<% end %>
My original block without the attempt at linking:
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
<%= link_to 'Show', profile %>
</div>
</div>
<% end %>
</div>
My Controller:
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy, :id]
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
end
# GET /profiles/1
# GET /profiles/1.json
def show
end
# GET /profiles/new
def new
#profile = Profile.new
end
#...
Your first example is problematic in many ways - you have links inside links. I'm not exactly sure what you're looking to output from this - but basically you need the
<%= link_to root_path do %>
<div>Hey!</div>
<% end %>
behavior to replace where you have <%= link_to 'Show', profile %>
Something along the lines of:
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
<%= link_to profile do %>
<div>
fancy pants stuff here
</div>
<% end %>
</div>
</div>
<% end %>
</div>
If you can give me some guidance on what you want in the div I can post you some code to achieve that, I'm just not clear on what you are looking for exactly.
Another example could be (if you wanted more of the pieces to fall inside that <div></div>:
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= link_to profile do %>
<div>
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
... more fancy pants stuff here ...
</div>
<% end %>
</div>
</div>
<% end %>
</div>

Rails - Show associated data on Index view

I'm struggling to have a belongs_to model iterate correctly inside a partial in an index page.
Classes:
class Chapter < ActiveRecord::Base
attr_accessible :name, :chapter_num,
belongs_to :chapter
#fields: :id, :name, :chapter_num
end
class County < ActiveRecord::Base
attr_accessible :name, :county_num, :chapter_id
has_many :counties
#fields: :id, :name, :county_num, :chapter_id
end
class ChaptersController < ApplicationController
def index
#chapters = Chapter.all
#counties = County.all(:joins => :chapter, :select => "counties.*, chapters.id")
end
end
app/views/chapters/index.html.erb:
<h1>Chapter Index</h1>
<%= render #chapters %>
<br />
<%= link_to "Add a new Chapter", new_chapter_path, class: "btn btn-large btn-primary" %>
app/views/chapters/_chapter.html.erb:
<div class="row">
<div class="span5 offset1"><h4><%= link_to chapter.name, edit_chapter_path(chapter.id) %></h4></div>
<div class="span2"><h4><%= chapter.chapter_num %></h4></div>
</div>
<!-- here's where the problem starts -->
<% #counties.each do |county| %>
<div class="row">
<div class="span4 offset1"><%= county.name %></div>
<div class="span4 offset1"><%= county.county_num %></div>
<div class="span2"><%= link_to 'edit', '#' %></div>
</div>
<% end %>
<%= link_to "New county", new_county_path %>
<hr>
The current code shows the screenshot below. The problem is it's iterating through all the counties, not just the counties associated with a given chapter.
How do I add a chapter specific variable within the partial that will cause the counties to iterate based upon the :chapter_id field since I'm in the index view, not the show view?
class ChaptersController < ApplicationController
def index
#chapters = Chapter.all
# #counties = County.all(:joins => :chapter, :select => "counties.*, chapters.id")
end
end
View:
<% chapter.counties.each do |county| %>
I think something like this would work for you:
<%= #chapters.each do |chapter| %>
<div class="row">
<div class="span5 offset1"><h4><%= link_to chapter.name, edit_chapter_path(chapter.id) %></h4></div>
<div class="span2"><h4><%= chapter.chapter_num %></h4></div>
</div
<% chapter.counties.each do |county| %>
<div class="row">
<div class="span4 offset1"><%= county.name %></div>
<div class="span4 offset1"><%= county.county_num %></div>
<div class="span2"><%= link_to 'edit', '#' %></div>
</div>
<% end %>
<%= link_to "New county", new_chapter_county_path(chapter) %>
<% end %>
Note that the key is to understand that because each chapter has many counties, you should iterate through the counties of each chapter via chapter.counties.each which will give you only the counties that belong to that particular chapter.
Also note the different link_to path for creating a new county. If you have your routes set up such that counties are nested under chapters, you should be able to do new_chapter_county_path(chapter)

Resources