When do you use <% -%> instead of <% %> - ruby-on-rails

I've noticed that in some lines of rails views, this is used:
<% # Code... -%>
instead of:
<% # Code... %>
What is the difference?

<ul>
<% #posts.each do |post| -%>
<li><%=post.title%></li>
<% end -%>
</ul>
There will be no new lines in between the <ul> and first <li> and the last closing </li> and </ul>. If the - was omitted, there would.

The different options for evaluating code in ERB are as follows (they can be accessed in Textmate using Ctrl-Shift-. ):
<% %> Just evaluate the contents.
<%= %> Evaluate the contents and puts the result.
<%= -%> Evaluate the contents and prints the result.
<%# %> The contents is treated as a comment and not outputted.
Notice the difference between puts and print. Puts always adds a new line at the end of the string whereas print doesnt.
Basically, the -%> says don't output a new line at the end.

Consider this
<div>
<% if #some_var == some_value %>
<p>Some message</p>
<% end %>
</div>
The code above yields to the HTML below if the #some_var is some_value
<div>
<p>Some message</p>
</div>
If you've put - in the closing tag, then the ERB interpreter would remove the new lines for those with code tag including - and result in the following
<div>
<p>Some message</p>
</div>
This is useful if you need to have a good looking code for HTML. Sometimes you'll find it useful when working sideby side with a designer
Hope this helps.

A little late, but I think it's worth pointing out that you can also do this:
<%- #posts.each do |post| -%>
<li><%= post.title %></li>
<%- end %>
This strips away any whitespace in front.

Related

Ruby on Rails - Underline words if they appear in dynamically generated text using Ruby

I am trying to underline words that are dynamically generated by the debug(params) method provided by rails. I have something below, but it obviously does not work, plus what I have below is attempt to try and change the words using methods that I already know about (like the .upcase method). I was hoping to underline the word controller if it appears in the text using only Ruby. Can anyone help me out here?
<%= debug(params) if Rails.env.development? %>
<% if debug(params).include?('controller:') %>
<%= 'controller'.upcase %>
<% end %>
thanks
edit:
I should add that debug(params) is a method defined by RAILS, I was able to do the following which seems even more off, so far the answers have not been correct to what I want to do.
<% if Rails.env.development? %>
<% debug_method = debug(params).split.each do |word| %>
<% if word == 'controller:' %>
<ul><% word.upcase %></ul>
<% end %>
<% end %>
<%= debug_method.join %>
<% end %>
which returns the following text: https://ibb.co/cvnEpw , keep the answers coming in though. I want to get the words in the original box (that's generated by the method to underline the controller word https://ibb.co/jmSm2G).
use <u></u> tag
<%= debug(params) if Rails.env.development? %>
<% if debug(params).include?('controller:') %>
<u><%= 'controller'.upcase %></u>
<% end %>
example here
Provide the css to generate html element:
p { text-decoration: underline; }
Add html elemnt to wrap your words:
<%= debug(params) if Rails.env.development? %>
<% if debug(params).include?('controller:') %>
<p> <%= 'controller'.upcase %> </p>
<% end %>
The answer to the question is below. I had to use the .gsub and .html_safe methods.
<%= debug(params).gsub("controller:", "<u>controller:</u>").html_safe %>
This code keeps the existing html & css generated by rails intact

Find all entities in database and show them if they exist, gives error: no block given yield

How to make this code work?
<%= articles= Article.find_each
if articles
a.each do |a| %>
****some html****
<% end %>
<% end %>
right now it gives me an error:
no block given (yield)
It's hard to tell because your code is such a mess but i think you are trying to do this:
<% Article.all.each do |article| %>
<!-- some html - reference the local variable `article` in here, inside erb tags, eg -->
<div>
<%= article.name %>
</div>
<% end %>
EDIT: the above code will work fine (by which i mean happily generate no html at all) if there are no Article records in the db. Sometimes in this situation you might want to display some sort of extra info, like "You haven't created any Articles yet" or something. if this is the case you could do something like this:
<!-- typically this variable would be defined in the controller -->
<% #articles = Article.all %>
<% if #articles.blank? %>
<p>You haven't created any Articles yet</p>
<% else %>
<% Article.all.each do |article| %>
<!-- some html - reference the local variable `article` in here, inside erb tags, eg -->
<div>
<%= article.name %>
</div>
<% end %>
<% end %>

Getting extra information when looping in Ruby

I'm using the each do loop correctly, and not getting errors when looping an active record base. But for some reason, I am getting extra information at the end.
Here's what my controller looks like:
def archivedBlogs
#compsci = Compsci.all
#personalb = Personalb.all
end
And here is the code I have in the view page:
<div class="panel">
<ul>
<%= #compsci.each do |blog| %>
<li><%= blog.title %></li>
<% end %>
</ul>
</div>
But as you can see, I'm getting extra stuff at the end:
How can I fix it so that it only prints the blog titles?
Change
<%= #compsci.each do |blog| %>
to
<% #compsci.each do |blog| %>

not displaying several html blocks if condition not met in ruby

Im trying to restrict the information being shown if data in not available.
In my view.rb file, I have something like this
<% if #content != nil %>
<div>
<h3>....</h3>
<% #content[0..3].each do |something| %>
<li> .... <li>
<% end %>
<% #content[4..5].each do |something| %>
<li> .... <li>
<% end %>
<% #content[5..11].each do |something| %>
<li> .... <li>
<% end %>
<div>
<% end %>
how ever even if content is nil, lines like content[4..5].each do |something| is being run and throwing errors for obvious reasons.
How do I get multiple blocks of html and ruby code to be ignored if condition isn't being met?
If the code <% content[4..5].each do |something| %> is executed, then #content IS NOT nil, there is no way ruby could be wrong about that.
BUT, if it is something like an empty array or a blank string then it will pass the test. In order to cover a wide range of possible "nil-like" values (nil, empty, blank...) use:
<% unless #content.blank? %>
And let me know if it helps.
you can use:
<% unless #content.nil? %>
#true
<%else%>
#false
<%end%>
Are you sure #content is surely nil? Please be aware that an object can be empty while it is not nil.
Eg:
#content=[]
or
#content={}
will make hold true for #content!=nil since it is not actually not nil. A reference is nil if it is never instantiated before.
If you are storing data to #content via a database query like Modelname,All , then you will get an empty array instead of a null (nil) object.
Also, if you are recieving #content from user as request parameter, then if the GET request contains name of the parameter but not any value, then again #content is empty but not nil.
ie http://yourdomain.com/somecontroller/index?name=10&age=
will have params[:age] as empty nil.
Solution:
<% if #content.to_s.empty? != true %>
<div>
<h3>....</h3>
<% content[0..3].each do |something| %>
<li> .... <li>
<% end %>
<% content[4..5].each do |something| %>
<li> .... <li>
<% end %>
<% content[5..11].each do |something| %>
<li> .... <li>
<% end %>
<div>
<% end %>

Can one use conditions and loops on a single line in Ruby?

How would one go about turning the following code into the latter?
<div id="faqs">
<% if #faqs.length > 0 %>
<% #faqs.each do |faq| %>
<div class="faq">
<strong>Q:</strong> <%= faq.question %>
<br />
<strong>A:</strong> <%= faq.answer %>
</div>
<% end %>
<% else %>
<p>No FAQs to display.</p>
<% end %>
</div>
<div id="faqs">
<% #faqs.empty? ? content_tag(:p, "No FAQs to display.") : #faqs.each do |faq| %>
<div class="faq">
<strong>Q:</strong> <%= faq.question %>
<br />
<strong>A:</strong> <%= faq.answer %>
</div>
<% end %>
</div>
I'm curious as to whether I can get the latter code to work. The only element of it that is failing at the moment is that the content_tag() is not displaying - this is due to the fact that I'm not using printable ruby tags (<%= # %>) but using them will dump out the FAQ objects underneath the content.
I considered the use of puts() to print the content_tag() while inside the ruby tags but that didn't work.
I've tried to search for this issue but haven't yielded anything useful.
Is this achievable and if so, does it have any benefits other than being prettier?
One way to make the later code to work if you can put the body of the loop in a helper function and return the out put of content_tag from that. The line in view file might be somewhat like this.
<%= #faqs.empty? ? content_tag(:p, "No FAQs to display.") : printList(#faqs) %>
and your printList function will return the output of nested content_tags. You can make a generic list printing function which can be used for any list.
Something so obvious but still shared.
This should work (for clarity, I moved FAQ tag generation in separate helper method):
<div id="faqs">
<%= raw (#faqs.empty? ? content_tag(:p, "No FAQs to display.") : #faqs.map { |faq| faq_div(faq) }.join) %>
</div>
or, perhaps more clean:
<div id="faqs">
<%= content_tag(:p, "No FAQs to display.") if #faqs.empty? %>
<%= raw #faqs.map { |faq| faq_div(faq) }.join %>
</div>
meanwhile, in helpers:
def faq_div(faq)
'<div class="faq"><strong>Q:</strong> %s<br /><strong>A:</strong> %s</div>' % [faq.question, faq.answer]
end
This should work:
<% if #faqs.each do |faq| %>
<div class="faq">
<strong>Q:</strong> <%= faq.question %>
<br />
<strong>A:</strong> <%= faq.answer %>
</div>
<% end.empty? %>
<p>No FAQs to display.</p>
<% end %>

Resources