as i'm new to ruby and rails in general i would have a short question cause i'm stuck at a minor issue.
I'm calling a content API from my controller and looping thru the response in the view directly. The main problem is: If one of the objects, has an empty value which i'm calling..it breaks the view.
Question would be how can i scip the elements which are emtpy...in example if post["heroimage"]["url"] is empty?
Example view:
<div class="gallery">
<% #blog.each do |post| %>
<a target="_blank" href="blog/<%= post["id"] %>">
<img src="<%= #host + post["heroimage"]["url"]%>" alt="" width="600" height="400">
</a>
<div class="desc"><%= post['description'] %></div>
<% end %>
</div>
There is nothing Rails or Rails views specific about your question. What you're trying to do is skip elements in an each loop in Ruby, and the answer is, next
somethings.each do |thing|
next if thing.nil?
# .. does not get called if thing is nil
end
From what I understand from the question and your comments you can use,
post.dig("heroimage", "url")
here is the link to dig method documentation. If you want to skip the image in case of empty url you can do something like this
<div class="gallery">
<% #blog.each do |post| %>
<a target="_blank" href="blog/<%= post["id"] %>">
<% if post.dig("heroimage", "url") %>
<img src="<%= #host + post["heroimage"]["url"]%>" alt="" width="600" height="400">
<% end %>
</a>
<div class="desc"><%= post['description'] %></div>
<% end %>
</div>
This will still show the title even if the image URL is empty.
Related
I am working on an app where I display current trending videos on YouTube (thumbnail, video title and channel title) via YoutubeDataApi. I would like to access to the correct URL whenever I click on the thumbnail or the title of a trending video.
This is the code I'm using in my controller:
# frozen_string_literal: true
class WelcomeController < ApplicationController
def index
youtube_data_api = YoutubeDataApi.new.client
#result, #errors = youtube_data_api.list_videos 'snippet, id', chart: 'mostPopular', region_code: 'FR', max_results: '50'
end
end
And this is the code I use in my view:
<div style="margin:0 auto; padding:20px 0;">
<% #result.items.each do |video| %>
<a href="https://www.youtube.com/watch?v=#{video_id}" target="_blank" style="color:black"><img src="<%= video.snippet.thumbnails.default.url %>" height="90" width="120">
<div id="channel_title">
<u><b><%= video.snippet.channel_title %></u></b>
</div>
<div id="video_title" style="margin-bottom: 50px;">
<i><%= video.snippet.title %></i>
</div>
</a>
<% end %>
Gem used in this app: gem 'google-api-client', '>0.7'
Could anyone please help me? Thanks in advance
Which gem are you using so we can see what you have to work with a little better.
Just take this with a grain of salt but your image has a src "<%= video.snippet.thumbnails.default.url %>"
Does that url point to the video url? If it does just change your href value to that video.snippet.thumbnails.default.url.
Currently with that href all of your videos will open a new tab to "https://www.youtube.com/feed/trending"
Is there a url on video.snippet (video.snippet.url) ?
Oh also you will need to wrap an around both the title and the thumbnail so that when you click on them it will link. With your loop you are getting the data for each individual video so if you can get the right url you just need to put links around everything and you should be good.
EDIT:
I think I have the answer for you. You are already sending off to retrieve the id's of the videos to the api so all you have to do to get them is do, `video.id
v=#{video.id} instead of video_id unless you make another variable called that and set it equal to video.id.
in your view loop:
<div style="margin:0 auto; padding:20px 0;">
<% #result.items.each do |video| %>
<a href="https://www.youtube.com/watch?v=<%= #{video.id} %>" target="_blank" style="color:black"><img src="<%= video.snippet.thumbnails.default.url %>" height="90" width="120">
<div id="channel_title">
<u><b><%= video.snippet.channel_title %></u></b>
</div>
<div id="video_title" style="margin-bottom: 50px;">
<i><%= video.snippet.title %></i>
</div>
</a>
<% end %>
So just simply the variable injected in your a href changes from video_id to video.id. However what youtube gives you is simply the video id not the full link, as you already noticed. With that slight ruby variable change you should be good to go! :)
Oh forgot to mention the ruby won't show up unless you throw in an erb like tag like shown above.
A possibly nicer way of doing the same thing would be to do:
<%= link_to "https://www.youtube.com/watch?v=#{video.id}", style="color: black;", target="_blank", style="color: black;" do %>
.... (stuff you are wrapping)
<% end %>
So altogether:
<div style="margin:0 auto; padding:20px 0;">
<% #result.items.each do |video| %>
<%= link_to "https://www.youtube.com/watch?v=#{video_id}", style="color: black;", target="_blank", style="color: black;" do %>
<img src="<%= video.snippet.thumbnails.default.url %>" height="90" width="120">
<div id="channel_title">
<u><b><%= video.snippet.channel_title %></u></b>
</div>
<div id="video_title" style="margin-bottom: 50px;">
<i><%= video.snippet.title %></i>
</div>
<% end %>
<% end %>
https://api.rubyonrails.org/v5.2.1/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
Cheers
Can anyone tell me whats wrong with this section of code? I recently got this to work, but found out soon after the functionality for the Fancybox gallery stopped working. The a link element is only a sliver compared to the over all element. Im not sure if thats it. I know the most recent edit I made was to fix the surrounding row from .row-fluid to .row since that broke my layout. Below is the code:
<body id="portfolio">
<div class="container-fluid" id="particles-js"></div>
<%= render 'layouts/altmenu_gallery' %>
<h1>Portfolio</h1>
<div id="gallery" class="container-fluid">
<% #photos.each_slice(4) do |group| %>
<div class="row ">
<% group.compact.each do |photo| %>
<div class= "col-md-3">
<a class="fancybox" data-fancybox="gallery" href="<%=image_path photo.file_url %>" data-caption="<%= photo.description %>">
<%= image_tag photo.file_url, class:' img-fluid img-thumbnail' if photo.file.present? %>
</a>
</div>
<% end %>
</div>
<% end %>
<br class="clear">
</div>
<%= link_to 'New Photo', new_photo_path %>
</body>
Sorry, but it is not possible to tell without seeing the actual html code or, preferably, live demo. Maybe this issue arises because you have not escaped photo.description and that breaks html code, but, as I said, I can not be sure.
I am trying to create a hover over action for items inside of a dynamically created loop. I have no idea what the object names are or how many there are. As of now, I have the list printed correctly and a hover over working, however the hover over only prints the info from the first item, no matter which one you are hovering over
<% #reward_definitions_with_user_points.each do |definition| %>
<li>
<a href="#" data-class="popover-inside" data-toggle="popover-follow" data-placement="right" data-btn-edit="hover" data-target="#point-tracker-popover">
<%= definition.first.name %><span class="points"><%= format_points(definition.second) %> pts.</span>
</a>
<div id="point-tracker-popover" style="display:none">
<div class="popover-title"><%=definition.first.name%></div>
<div class="popover-content">
<div class="popover-inner popover-lg">
<%=definition.first.description%><span class="points"><%= format_points(definition.first.points) %> pts.</span>
</div>
</div>
</div>
</li>
<% end %>
For example: if the my list is a,b,c,d,e,f and I want the hover over to display each letter in sequence when activated. However it will display 'a' in the hoverover no matter which one the mouse activates.
You should probably mention that the problem you're having is with popovers. Also showing the html generated by your loop would be helpful. You seem to imply from the tags that popovers are an html5 thing, but I thought they were a part of twitter-bootstrap?
Having said all that...
What you are describing is clearly related to data-target="#point-tracker-popover". Which I believe is pointing to id="point-tracker-popover". The div with this id is being generated inside of your loop (having multiple elements with the same id is bad and is why you are experiencing the behavior you mentioned).
Changing your loop to use each_with_index should fix your problem.
<% #reward_definitions_with_user_points.each_with_index do |definition, index| %>
<li>
<a href="#" data-class="popover-inside" data-toggle="popover-follow" data-placement="right" data-btn-edit="hover" data-target="#point-tracker-popover-<%= index %>">
<%= definition.first.name %><span class="points"><%= format_points(definition.second) %> pts.</span>
</a>
<div id="point-tracker-popover-<%= index %>" style="display:none">
<div class="popover-title"><%=definition.first.name%></div>
<div class="popover-content">
<div class="popover-inner popover-lg">
<%=definition.first.description%><span class="points"><%= format_points(definition.first.points) %> pts.</span>
</div>
</div>
</div>
</li>
<% end %>
Of course, you may be able to simply change the target to a class like data-target=".point-tracker-popover" and change the id="point-tracker-popover" to be class="point-tracker-popover"; which would be a much cleaner approach. I am really not familiar with popovers, though, so I cannot say if this is the only problem you have, or if the second approach will work.
Question about Rails4, I trying to retrieve the "Find Stuff" variable, in the erb form. This
is a search field, using zurb foundation - so the extra styling annotations floating around.
I don't have a model as this is just a form for reading the search input field - which is
in the tag, with placeholder as "Find Stuff".
To use normal Rails4 terminology, I would
like to pass the value of the "Find Stuff" field to the salutation controller, and I tried
many ways, but was unsuccessful, when I used render params[:post].inpect, it shows nil -the
variables that I pass to the controller, on clicking on the "Search" link_to, link. I tried adding an id field to the tag, and that too showed nil on render params[:post].inspect.
Any help, thanks in anticipation.
hello.html.erb form below.
<html>
<body>
<nav class="top-bar" data-topbar>
<ul class="title-area">
<li class="name">
<h1>Hello World!</h1>
</li>
<li class="toggle-topbar menu-icon"><span>Menu</span>
</li>
</ul>
<ul class="right">
<li class="has-form">
<div class="row collapse">
<div class="large-8 small-9 columns">
<input type="text" placeholder="Find Stuff" >
</div>
<div class="large-4 small-3 columns">
<%= link_to "", :controller =>
'salutation', :action =>'hello',
:class=>"alert button expand" %>
</div>
</div>
</li>
</ul>
</section>
</nav>
</body>
</html>
Controller follows
Salutation Controller follows
class SalutationController < ApplicationController
def new
#test = ''
end
def hello
#message = 'Hello World!'
#test = params[:Find_Stuff]
end
end
Wrap your search box in a form element, give your input a name and away you go. You can use the rails form helpers as well - see http://guides.rubyonrails.org/form_helpers.html which has a nice intro to creating a search form
<div class="row collapse">
<%= form_tag("/salutation/hello", method: "post") do %>
<div class="large-8 small-9 columns">
<%= text_field_tag(:find_stuff) %>
</div>
<div class="large-4 small-3 columns">
<%= submit_tag("Search") %>
</div>
<% end %>
</div>
Further to #slapthelownote's answer, the reason you're getting an error is because you're not passing any params to your controller
We've got something like what you want working at http://firststopcosmeticshop.co.uk (top search box) -- using a form_tag
If you want to see live code, I'll be happy to post!
Params
Using a form allows you to set various variables & then submit them to the controller as you've set them. I'd recommend using the form in the other answer, but to understand how it works, you need to read up on the Rails forms tutorial
Basically, the params hash is populated in the middleware of Rails -- from any data sent by HTTP to your backend
With links, you can only send GET params (domain.com/route¶ms=value), whilst with HTML forms, you can set POST params which are passed through the browser (not the URL)
I m using carousel to display the images. I ve uploaded the images in the cloud. But somehow it is repeating it self.
Here is my code
div id="myCarousel" class="carousel slide">
<div class="carousell-inner">
<% #img.each_with_index do |i|%>
<% if i.gallery == "Art"%>
<div class="active item">
<%= image_tag (i.image.url) %>
</div>
<% i.next%> <!-- For incrementing the i value but it is not working-->
<div class="item">
<%= image_tag (i.image.url)%>
</div>
<%end%>
<%end%>
</div>
</div>
What i want is in the active item it should display the first url of the image array and in the inactive item (which ll be active afterwards) should have the other images. It should not repeat the images. Here it is repeating the image since the value of i is not changing.
I am starting to understand what you want :)
You can make your logic very simple, if you will separate your data.
<div id="myCarousel" class="carousel slide">
<div class="carousell-inner">
<% #img.keep_if{|i| i.gallery == "Art"}.each do |i|%>
<div class="active item">
<%= image_tag (i.image.url) %>
</div>
<%end%>
<% #img.keep_if{|i| i.gallery != "Art"}.each do |i|%>
<div class="item">
<%= image_tag (i.image.url)%>
</div>
<%end%>
</div>
</div>
And better to prepare your data in controller, not in view.
I first thought you needed each_with_index, but actually, you are only interested in images from the Art gallery, no telling if the first image is actually an Art image, so I tried as follows:
<div id="myCarousel" class="carousel slide">
<div class="carousell-inner">
<% art_images_counter = 0 %>
<% #img.each do |image|%>
<% if image.gallery == "Art" %>
<% if art_images_counter == 0 %>
<div class="active item">
<%= image_tag (image.image.url) %>
</div>
<% else %>
<div class="item">
<%= image_tag (image.image.url)%>
</div>
<% end %>
<% art_images_counter += 1 %>
<%end%>
<%end%>
</div>
</div>
Hope this helps.
ive found out the answer by doing it manually. First of all in the controller i ve found out all the images which belong to the Art Gallery by this code.
#image = Image.find_all_by_gallery("Art")
Now to display the first element of the array #image, we can use the simply #image.first and then we can call that first element of the array in the active item of carousel. Then for the item part the basic thing to understand is that if we directly call and display all the elements of the array then the first element of the array will also be display in this part. So the repetition can happen. To avoid this we can do like this:
i = #image.count
#image[1..i]
So that the first element will not repeat in the `item' part of the carousel.
Hope it might help others. Thanks for giving time.