I have a helper that looks like this:
if current_user.find_voted_items(vote_scope: :inspired).include?(post)
link_to vote_inspired_post_path(post, vote_scope: :inspired), method: :post, data: { confirm: 'Are you sure this post Inspires you?' }, class: "btn btn-default" do
"<i class='fa fa-lightbulb-o'></i> <br />Inspired".html_safe
end
link_to vote_happy_post_path(post, vote_scope: :happy), method: :post, data: { confirm: 'Are you sure this post makes you happy?' }, class: "btn btn-success" do
"<i class='fa fa-smile-o'></i> <br />Happy".html_safe
end
link_to vote_disappointed_post_path(post, vote_scope: :disappointed), method: :post, data: { confirm: 'Are you sure this post disappointed you?' }, class: "btn btn-info" do
"<i class='fa fa-meh-o'></i> <br />Disappointed".html_safe
end
link_to vote_upset_post_path(post, vote_scope: :upset), method: :post, data: { confirm: 'Are you sure this post upsets you?' }, class: "btn btn-inverse" do
"<i class='fa fa-frown-o'></i> <br />Upset".html_safe
end
end
I need all the links and their nested <i>
tags to be rendered - but for some reason, this version is just rendering the last line.
All of that is inside a method called show_vote_buttons(post)
, that is being called like this in the view: <%= show_vote_buttons(@post) %>
What's the best way to tackle this?
Basically, the reason behind this is that <%= %>
renders the output of show_vote_buttons
method. This method doesn't explicitly return anything, so the last evaluated expression is returned, in your case, the last link_to
output.
In a general case, if you have not used a helper method and just pasted it's body instead with multiple link_to
calls, you would get the same behavior. The reason is similar: <%= %>
does not render each link_to
, it executes code inside <%= %>
and then outputs the result of last evaluated expression.
I see two different approaches to change the output:
<<
and parenthesis ()
around each link_to
;"
and interpolating each link_to
output with #{}
in it;concat
;<%= %>
to output each link_to
.P.S. After testing all four methods I've come to a conclusion (here comes a personal opinion) that the second method is more preferable, at least because it keeps rendering in the views and avoids concatenation that can look messy. Similar approach is used, for example, in the Devise gem, where all shared links are located in the app/views/devise/shared/_links.html.erb
partial.
but for some reason, this version is just rendering the last line.
That reason is because in Ruby, if a method doesn't have an explicit return
, then the returned value of a method is the value of the last line that got executed before a method exited. If you want to return multiple values from a method, use the return
keyword and comma-separate your values.
#will return an array [1,2,3]
def some_method
return 1,2,3
end
Also, I do agree with the other answers that your code should be more DRY, but I was simply trying to clarify your original question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With