Rails link_to_if not hiding links correctly - ruby-on-rails

For some reason my link_to_if line works, but appears on every show view for my model (Company).
Here's the code:
<% #customers.each do |customer| %>
<li>
<%= link_to_if customer.company_id == #company.id, "#{customer.first_name} #{customer.last_name}", customer_path(customer[:id]) %>
</li>
<% end %>
The issue: I have Customer1 linked to CompanyX. When I go to CompanyZ it shows Customer1, but the link is not a hyperlink. it's just plaintext, and not even supposed to be showing up. However on CompanyX's view, the link works fine. What am I doing wrong here?

If you read the documentation of link_to_if (https://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to_if), it clearly says that [if false] only the name is returned.
In the doc you can find that the (optional) block given is rendered in the false case. So in your case you could pass it an empty block:
<%= link_to_if false, customer_path(customer[:id]) {} %>
In my opinion, if you want to display the link only if one or more customer(s) from #customers are associated to that #company, you should do it this way:
<% #customers.where(company_id: #company.id).each do |customer| %>
<li>
<%= link_to "#{customer.first_name} #{customer.last_name}", customer_path(customer[:id]) %>
</li>
<% %>

if you want to hide some records you can do from from controller to control customers based company
#customers = Company.find(:id).customers
then in your views you can just show it without to compare it
<% #customers.each do |customer| %>
<li>
<%= link_to "#{customer.first_name} #{customer.last_name}", customer_path(customer[:id]) %>
</li>
<% end %>

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

List of articles also displays database info for all articles in View

I am doing the Jumpstart tutorial where you have to create a blog in ruby on rails. It is going fine but I have not managed to figure out one thing.
The root page is supposed to show a list of articles. And it does. Only it also shows this extra bit:
Article list and unwanted part at the bottom
The code I have in the view:
<h1> All Articles </h1>
<ul id="articles">
<%= #articles.each do |article| %>
<li>
<%= link_to article.title, article_path(article), class: 'article_title' %>
</li>
<% end %>
</ul>
<%= link_to "Create New Article", new_article_path, class: 'new_article' %>
And here is the relevant code in the controller
def index
#articles = Article.all
end
I would appreciate any help on why this is happening.
Take out the = sign of your loop
So:
<% #articles.each do |article| %>
In Embedded Ruby (ERB), the difference between <% %> and <%= %> is not simply cosmetic; the latter actually prints the results of the line of code into the html. As such, in your line:
<%= #articles.each do |article| %>
...You are actually printing the results of running that line of code and displaying it. Or, more specifically, you're displaying loop itself, not just the results of looping through the #articles collection. You'll get a lot of gibberish from haphazardly using the <%= %> notation. Just look at when you play around in the console/debugger; running these lines of code makes a lot of noise!
To fix your problem, your loop through #articles should simply look like this:
# No "=" here!
<% #articles.each do |article| %>
<li>
<%= link_to article.title, article_path(article), class: 'article_title' %>
</li>
<% end %>
For more information on ERB syntax, look here.
For another stack overflow question encompassing this and a few additional notation, look here.
<% #articles.each do |article| %>
<%= content_tag :li, link_to(article.title, article, class: 'article_title') %>
<% end %>
Struggled with the same issue for 2 days when starting.

Ruby on Rails how to get last query?

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.

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.

For the first x in array?

I imagine this has a rather simple answer
<% for user in #users %>
<li>
<%= link_to user.username, user %>
</li>
<% end %>
Taking my simple example above, how would I apply a class to my <li> to the first three instances returned?
Secondly, how could I just have the the second two items have a different class from the first one? as in 1..2
Either you could count manually (which is kinda ugly):
<% i = 0 %>
<% for user in #users %>
<li class=<%= (i < 3 ? "foo" : "bar") %>>
<%= link_to user.username, user %>
</li>
<% i = i.next %>
<% end %>
or use each_with_index
<% #users.each_with_index do |user, i| %>
<li class=<%= (i < 3 ? "foo" : "bar") %>>
<%= link_to user.username, user %>
</li>
<% end %>
Once you get to more complex things than i < 3 (like your 1..2 issue) you should think about a helper_method (in helpers) like class_by_position(pos) so that you can write
<li class=<%= class_by_position(i) %>>
The :first-child pseudoselector might be a better way to go, but you'll need to have a counter variable that keeps track of the iterations to do it your way.
Your question is a little vague. I can't tell if you want to stop processing the array after the first x, or not.
If you're just looking to stop after the first x items, or just looking for the 2nd and 3rd items the solution is to use a slice.
Example: just the first 3:
#user[0,3].each do |user|
... # only executed for user = #user[0],user = #user[1] and user = #user[3]
end
Example: just the second and third:
#user[1,2].each do |user|
... #only only executed for user = #user[1] and user = #user[3]
end
And here's a more specific answer to your question using these new concepts and the content_tag to programatically decide the class of the list item. If you're going to be doing this often, makes a great candidate for a function.
<% first = true %>
<% #user[0,2].each do |user| %>
<% content_tag :li,
:class => first ? "class-for-first-item" : "class-for-2nd-&-3rd" do %>
<%= link_to user.username, user %>
<% end %>
<% first = false %>
<% end %>
<!-- Now to do the rest of them:-->
<% #user[3,-1].each do |user| %>
<% content_tag :li, :class => "class-for-rest" do %>
<%= link_to user.username, user %>
<% end %>
<% end %>

Resources