Ruby on Rails how to get last query? - ruby-on-rails

I'm having trouble trying to figure out when I reached the end of my query. So what I want to do is list all the records in my database that begin with the letter A which I got however I want to output a message if the query turns out blank. When I try I get a bunch of my custom messages even the query didn't turn out blank. Is there any way to tell if I've reached EOF in ruby on rails?
Sample
<div id = "content-A">
<p>A</p>
<% #animes.each do |anime| %>
<% if anime.aname.starts_with?('A') %>
<%= link_to anime.aname, {:action => 'list'} %>
<% else %>
<p>No anime listed in this Category :( </p>
<%end%>
<%end %>
</div>

I believe you want sth like:
<% animes_group = #animes.group_by {|anime| anime.aname.to_s[0].upcase}
('A'..'Z').each do |letter| %>
<div id="content-<%= letter %>">
<p><%= letter %></p>
<% if animes = animes_group[letter] %>
<% animes.each do |anime| %>
<%= link_to anime.aname, {:action => 'list'} %>
<% end %>
<% else %>
<p>No anime listed in this Category :( </p>
<%end%>
<% end %>
You should consider moving some of the logic to the controller here, however what is to be moved depends on many factors like whether #animes are being used anywhere else etc.

Related

Strange output from rails each do

Rails each do method is acting strangely and I do not know why.
controller
def index
#fabric_guides = FabricGuide.with_attached_image.all.order(:name)
end
index.html.erb
<div class="guide-items">
<%= #fabric_guides.each do |fabric| %>
<div class="guide-container">
<%= link_to fabric_guide_path(slug: fabric.slug) do %>
<%= image_tag fabric.image if fabric.image.attached? %>
<% end %>
<div class="guide-info">
<p class="g-name">
<%= link_to fabric.name,
fabric_guide_path(slug: fabric.slug) %>
</p>
</div>
</div>
<% end %>
</div>
I have two FabricGuide records so I expect two "guide-container" but I get three. Or more precisely I get two guide containers and a third block of text containing all the content from the last FabricGuide record.
I have almost an identical setup for articles and have never encountered this problem. I'd happily share more information if needed. Thank you!
Please remove = equal sign from your each loop of view code
like below :-
<% #fabric_guides.each do |fabric| %>
...
...
<% end %>
you have used this <%= #fabric_guides.each do |fabric| %> in your view that's why it shows all record in DOM.
The expression for erb tags is <% %>
now if we want to print that tag too then we apply <%= %>

Rails how to make conditional inside iteration?

i'm trying to use a conditional inside a iteration but did not worked so, here the scenario:
in this case if the if the order or the product is present should just show the order and products with the feedback.
but even if is present show the feedback with odata and pdata.
someone know why?
<% #feedbacks.each do |feedback| %>
<% if order.present? && product.present? %>
<% order = feedback.order %>
<% product = order.product %>
<% else %>
<% odata = feedback.odata %>
<% pdata = odata.pdata %>
<% end %>
I guess this is what you are trying to do,
<% #feedbacks.each do |feedback| %>
<% if (order = feedback.order).present? && (product = feedback.product).present? %>
<%= order.title %>
<%= product.title %>
<% else %>
<%= (odata = feedback.odata).name %>
<%= odata.pdata.name %>
<% end %>
<% end %>
Note: title and name are assumed columns, replace it with your required/respected attribute.
Please go through this to understand the difference between various erb tags.
Comparison:
for the if condition you are trying to call order and product directly, which will throw error as they are related to feedback.
<% %> just executes the ruby code, you wanted to print the data so need to use <%= %>.
no need to save them in variable when you are not going to use it. I have saved them while checking the existence of the object in the condition and could use to display without querying the db.

Query "where" with ruby on rails

I've in my app, posts as ideas, and these ideas belongs to an activity and a status.
And I want to sort them by activity for one status so I did in my controller
#idees_en_place = Idee.where(statut_id= "2")
#activites = Activite.all
And in my view :
<% #activites.each do |activite| %>
<div class="idee en-place col-lg-5" style="background:#<%= activite.color%>">
<h2><%= activite.name %></h2>
<p>
<% #idees_en_place.where(activite_id = activite.id).limit(3).each do |idee| %>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>
<% end %>
But that doesn't work, in each part of an activity the ideas are not sorted.
I think it's a little mistake but I don't know how to resolve this
#idees_en_place = Idee.where(statut_id= "2")
There are two problems with this code.
First, id is a Integer type (unless you've defined it as String).
Second, its a key value you pass to where clause, and you pass these either as
:status_id => 2 # old hashrocket syntax
or
status_id: 2 # new syntax
The same goes with this part
#idees_en_place.where(activite_id = activite.id)
it should be
#idees_en_place.where(activite_id: activite.id)
In Controller
#idees_en_place = Idee.where(statut_id: 2)
#activites = Activite.all
In View
<% #activites.each do |activite| %>
<div class="idee en-place col-lg-5" style="background:#<%= activite.color%>">
<h2><%= activite.name %></h2>
<p>
<% #idees_en_place.where(activite_id: activite.id).limit(3).each do |idee| %>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>
<% end %>
I just wanna point out that you will run into an N+1 queries issue, to avoid this you should preload every thing, instead of doing queries in the views.
The controller:
#change if the association name is different
#activites = Activite.includes(:idees)
The view
<% #activites.each do |activite| %>
<div class="idee en-place col-lg-5" style="background:#<%= activite.color%>">
<h2><%= activite.name %></h2>
<p>
<% activitie.idees[0..2].each do |idee| %>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>
<% end %>
Notes:
I've used the [0..2] format because I wanted to avoid ActiveRecord from doing a new query, another method would be limiting the query using something like this
#activites = Activite.includes(:idees).merge(Idee.limit(3))
Then you won't need to use any limitation in the views, but I haven't tested this, don't have access on a rails machine right now.
I think that the following code will help you:
Since your Idee belong to activity and status that's why you have activity_id and status_id in your Idee table.
you may find out all the idee for a status by using:
Idee.where(:status_id => 2)
and you can sort Idee in Asc or desc order by using order
idees = Idee.join(:activity).where(:status_id => 2).order(:activity_id => :asc)
idees = Idee.join(:activity).where(:status_id => 2).order(:activity_id => :desc)
<% activity_id = -1%>
<#idees.each do |idee| %>
<div class="idee en-place col-lg-5" style="background:#<%= idee.activite.color%>">
<h2><%= idee.activity.name %></h2>
<p>
<% if activity_id != idee.activity_id %>
<% activity_id = idee.activity.id %>
<% counter = 0 %>
<% end %>
<% if counter < 3 %>
<% counter = counter + 1%>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>

Dont have a comma on the last iteration of an each loop in Rails

I want to print out a list of links separated by commas in Rails.
Heres what I've got:
<%= topics.each do |topic| %>
<a href="<%= topic.link %>" ><%= topic.name %></a>
,
<% end %>
Heres what I want:
Thing A,
Thing B,
Thing C
But right now I get an extra comma on the last iteration of the loop! What should I do?
One way of doing this is with map then Array#join:
<%= topics.map { |topic| link_to(topic.name, topic.link) }.join(',').html_safe %>
if you want to do minimum possible change to your code, you can use the following
<%= topics.each do |topic| %>
<a href="<%= topic.link %>" ><%= topic.name %></a>
<% if(topic != topics.last) %>
,
<% end %>
<% end %>
How about using each_with_index, and only put comma before the content unless it's not the first item.
<% topics.each_with_index do |topic, i| %>
<% if i > 0 %>
,
<% end %>
<%= topic.name %>
<% end %>
I made it in one line call (for active records collections) using the concat helper:
<% concat (',') if e.bills.last != b %>
concat is an ERB helper (TextHelper) to add some HTML without the <%= %> syntax, helpful to add few characters.
Here is the full code to make it clear:
<% event.bills.each do |b| %>
<%= link_to(b.number.to_s, bill_display_path(b)) %>
<% concat (',') if e.bills.last != b %>
<% end %>
Simply try this. It works for me
<%= topics.map{|p| p.topic.name}.join(",") %>
You can do the following to print out the comma for all items except for the last:
<% topics.each do |topic| %>
<%= topic %>
<%= "," if topic != topics.last %>
<% end %>
This will check if the current item in the loop is the last item, and will use the <%= %> syntax to output the comma.

Whats wrong with my simple If Else?

Im new to RoR/Ruby and i cant seem to get the simplest thing to work. (trust me, ive search google and reread docs, i dont know what wrong)
So in my main view, I added the following:
<%= if 1>2 %>
<%= print "helllloooo" %>
<%= else %>
<%= print "nada" %>
<%= end %>
And nothing is outputted..
**UPDATE**
Ok heres my new CORRECTED code and its STILL NOT WORKING
<th>
<% if 1 > 2 %>
<%= print "helllloooo" %>
<% else %>
<%= print "nada" %>
<% end %>
</th>
Your statements are not intended to be displayed so instead of
<%= if 1>2 %>
write
<% if 1 > 2 %>
Same thing for else and end
EDIT
<% if 1 > 2 %>
<%= "helllloooo" %> #option 1 to display dynamic data
<% else %>
nada #option 2 to display static data
<% end %>
You don't need to use print, or even ERB for the text. Also, your if, else, and end statements should be <%, not <%=:
<% if 1 > 2 %>
helllloooo
<% else %>
nada
<% end %>
<%= already means "print to the HTML response" in ERB (Ruby's own templating language).
So <%= print '...' means "print the return type of print '...'" which is nothing.
The right code would look like:
<% if 1>2 %>
<%= "helllloooo" %>
<% else %>
<%= "nada" %>
<% end %>
In fact you can even omit the <%= because you're just printing strings (not arbitrary objects):
<% if 1>2 %>
helllloooo
<% else %>
nada
<% end %>
The = is the problem. Use <% instead. <%= is for printing something, while <% is for instructions.
for dynamic content use: <%= %>

Resources