If else not working because it contains end within - ruby-on-rails

I have a a helper that contains a simple on and off switch. I know I have it working because it's working on other pages. However, on this particular page it won't work.. I think its because theres an end within the if else, so it ends the if else early. Here's the code:
I believe this part is working:
<% if popup == "off" %>
<% content_for :main do %>
<% end %>
This part not so much:
<% if popup == "off" %>
<% end %> << this end should be displayed if popup = off
<% end %>

You could do this:
<% if popup == "off" %>
<%= "<% end %>" %> << this end should be displayed if popup = off
<% end %>
or try this:
<% if popup == "off" %>
<% end %> << this end should be displayed if popup = off
<% end %>

If you just want the word end to be displayed, don't enclose it in tags. Anything enclosed in tags is interpreted as Ruby code, anything not is printed exactly as it is.
<% if popup == "off" %>
end << this will now be interpreted as text, not ruby code
<% end %>

ERB (and Ruby) doesn't work like that.
I think you're treating it like you are trying to end an HTML tag instead of an end to a Ruby block, and that you want everything in between those two code segments to run in the content_for block.
Here's what you need. Everything in between will be included in the content_for block:
<% if popup == "off" %>
<% content_for :main do %>
your block code will be evaluated here.
<% end %>
<% end %>

Seems all the suggestions of doing <%= "<% end %>" %> results in a syntax error.. May seem like easy way out by ended up just restructuring my app and got rid of the requirement of <% content_for :main do %>

Related

Ruby is adding weird spacing between words

My website is printing out elements such as (SnO), however, it should be printing SnO, but it is adding a weird space and it is printing like Sn O. It is adding a space between the element for no reason. My code is on the listed below.
<% saved_element = ""%>
<% sensor.base_material.elests.each_with_index do |elest, v| %>
<% if elest.element.include? "O" %>
<% saved_element = elest %>
<% else %>
<%=elest.element.split('-').last %>
<% if elest.stoich != 1 %>
<sub><%=elest.stoich.to_i%></sub>
<% end %>
<% end %>
<% if v == sensor.base_material.elests.length-1 %>
<%=saved_element.element.split('-').last%>
<% if saved_element.stoich != 1 %>
<sub><%=saved_element.stoich.to_i %></sub>
<% end %>
<% end %>
<% end %>
The code you show is full of white spaces (at the beginning of each line). Those are printed on the HTML and compacted as one space. Also, when you print a value, it adds an space at the end, you can supress that usign <%= ... -%> (note the dash at the end)
https://www.howtobuildsoftware.com/index.php/how-do/Nzr/ruby-on-rails-erb-suppressing-spaces-in-erb-template
Anyway, I would move all that logic to a helper method, that's what helper methods are for.

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

Is there a way to get the console to ignore certain errors?

Say I have an instance variable #n, and I'm calling <%= #n.title %> in my view.
If #n equals a valid record, then this will print normally. But if #n is blank or invalid, then the entire page will show an error message, because of this one little line.
Is there a way to get #n.title to just print nil if #n is nil or invalid?
I'm looking for a way to do this without conditional statements. For example, if I wanted to print
<%= #v1.title %>,<%= #v2.title %>,<%= #v3.title %>,<%= #v4.title %>,
if I wanted to use conditionals to print without errors, it would require 12 lines of code:
<% if #v1 %>
<%= #v1.title %>,
<% end %>
<% if #v2 %>
<%= #v2.title %>,
<% end %>
<% elsif #v3 %>
<%= #v3.title %>,
<% end %>
<% elsif #v4 %>
<%= #v4.title %>,
<% end %>
It seems a shame to use 12 lines on this. It would be nice to be able to accomplish the error-handling right when printing.
You can totally do this easily with the try() method. I use it all the time.
<%= #n.try( :title ) %>
That will return nil if #n is nil or if the title method doesn't exist on #n.
You can also chain them together like this:
#n.try( :title ).try( :to_s )
Or even use it on a hash:
#n.try( :[], 'name' ) # Which is the same as #n['name']
See http://api.rubyonrails.org/classes/Object.html#method-i-try
EDIT (Jan 11, 2016)
You can now use the "safe navigation operator" as of Ruby 2.3.0.
#n&.title&.to_s
As well as the Array#dig and Hash#dig methods introduced in Ruby 2.3.0.
hash = { 'name' => 'bob' }
hash.dig( 'name' ) # Which is the safe way to do hash['name']
You can add some logic to your view that differentiates between development (where some errors can be ignored) and production environments (where errors should cause your app to fail in an obvious and ugly manner). Ruby's nil has a "falsey" nature, so you can use that concept to your benefit as well.
<% if Rails.env.development? %>
<% if #n %>
<%= #n.title %>
<% else %>
<%= nil %>
<% end %>
<% else %>
<%= #n.title %>
<% end %>

Conditional line spacing in ERb partials

This is the code for an address partial I just wrote. People might put single line addresses in either street line, company name is optional, etc... It works exactly how I want it to, but I know that checking each variable twice is ugly and terrible.
<%= "#{a.name}" unless a.name.blank? %>
<% unless a.name.blank? %> <br> <% end %>
<%= "#{a.company_name}" unless a.company_name.blank? %>
<% unless a.company_name.blank? %> <br> <% end %>
<%= "#{a.street_1}" unless a.street_1.blank? %>
<% unless a.street_1.blank? %> <br> <% end %>
<%= "#{a.street_2}" unless a.street_2.blank? %>
<% unless a.street_2.blank? %> <br> <% end %>
<%= "#{a.city}, #{a.state} #{a.zip}" %>
So, my gratuitous use of unless aside, how should I be putting in a conditional line break?
Update:
As discussed below, it is dangerous to use .html_safe on user input. If you do use a helper method as suggested below, you must also sanitize all user input on the way into the database. I've rewritten the code above as:
<% unless a.name.blank? %>
<%= a.name %>
<br>
<% end %>
<% unless a.company_name.blank? %>
<%= a.company_name %>
<br>
<% end %>
<% unless a.street_1.blank? %>
<%= a.street_1 %>
<br>
<% end %>
<% unless a.street_2.blank? %>
<%= a.street_2 %>
<br>
<% end %>
<%= "#{a.city}, #{a.state}" %> <%= a.zip %>
The redundant checking was just me overcomplicating things. I'd strongly recommend against using .html_safe in a situation like this, since you create new problems for yourself: sanitizing the input, and remembering which fields are safe. Better to not override the sensible protection Rails provides.
There are many, many ways to go about cleaning it up, but a helper would be appropriate here:
module ApplicationHelper
def format_address(a)
top = [a.name, a.company_name, a.street_1, a.street_2]
top.reject! {|s| s.blank?} # remove null and empty values
"#{top.join('<br/>')}#{a.city}, #{a.state} #{a.zip}".html_safe
end
end
Then in your view:
<%= format_address(a) %>

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