Strings not displayed right - ruby-on-rails

So, I have this which displays emails to a user.
OLD CODE FOR REFERENCE:
<%= for email in #emails
# print the name
eml = email
eml
puts "<br>"
end
%>
FIXED, WORKING, STABLE CODE:
<% for email in #emails %>
<%= email %>
<br>
<% end %>
<%= puts #emails.inspect %>
As you can see, it was a problem of multiple line tag. Bazar that It would cause this problem, but not at all that it would cause A problem.
OLD:
And it is working great. One thing. So, EML is a ruby string with HIDDEN#HIDDEN.HIDDEN, but when it goes to display I get this on the rendered page: ["HIDDEN#HIDDEN.HIDDEN"], so why is it doing that? Inspected it, it isn't a hash. Just a string. What is happening here?

This syntax does not look quite right. If this is being rendered in a view using ERB, you probably want code that looks more like this:
<% #emails.each do |email| %>
<%= email %><br />
<% end %>
The way you have that written is very C#-looking. In Ruby it is more common to use the methods attached to the object. Enumerable objects like arrays could be iterated through using the each method and a special structure in Ruby called a block.
http://www.ruby-doc.org/core-2.1.0/Array.html#method-i-each

Related

Strings passed from controller to view in Rails arrive empty

I am trying to pass a string to my view from controller like this:
controller:
def index
#str = 'foo'
end
view:
String: <% #str %>
The variable itself seems to arrive because I get no error. However, it arrives empty (only "String" is in html, nothing else). And it seems to work great with other built-in types, e.g. Time. What am I missing here? I use Ruby 2.2.1 and Rails 4.
As others have said, you need to use
<%= #str %>
I'll give you an explanation as well - you use <% %> for when you need to run some Ruby code that you don't want displayed to the screen. For example, you might have conditional logic like
<% if user_signed_in? %>
<%= #welcome_string %>
<% end %>
Use <%= %> when you want to output, drop the '=' for conditional logic or anything that doesn't need to display.
in your view
String: <%= #str %>
In view user following code:
String: <%= #str %>
In your view, use:
<%= #str %>
As the other users have pointed out, you need to use <%=
The = is an ERB flag to so export the result of the code inside of the tags and put it into the DOM.
If you want to put some logic into your page that you don't want to evaluate, you leave the = out.
<% if user_wants_to_see_output? %>
<%= "User will see this" %>
<% end %>

In a rails view, how can I send output to view besides <%= %>?

Short version:
It seems weird to me to have rails code like, say,
<% if #list.empty
%><%= val %><%
end %>
Is there some way to do something like this?
<% if #list.empty
some_display_function_i_wish_existed val
end %>
Long version:
I have a model, tweet.rb, that overrides to_s. The to_s works fine.
I have a view that needs to output to_s for each tweet in #meme.tweets .
I've observed the following:
<% #meme.tweets.each do |tweet|
tweet
end %>
Result: no output
<% #meme.tweets.each do |tweet|
puts tweet # or tweet.to_s does the same thing
end %>
...Result: no output
<%= #meme.tweets.each do |tweet|
tweet
end %>
...Result: output is entire inspection of each tweet, not to_s
<%= #meme.tweets.each do |tweet|
puts tweet # or tweet.to_s does the same thing
end %>
...Result: output is entire inspection of each tweet, not to_s
<% #meme.tweets.each do |tweet| %>
<%= tweet %>
<% end %>
...Result: works as intended (outputs result of to_s for each tweet). So does:
<%= #meme.tweets.collect do |tweet|
tweet.to_s
end %>
...Result: works as intended.
I come from a PHP background, and don't really understand the rules here.
I know I can do it the way I did in the last example.
But could someone explain why none of the other examples work as I intend?
It seems to me that the rules APPEAR to be:
1) <%= something %> will take that thing, call to_s on it, which will default to inspect if not overridden.
2) <% something %> will execute something
Is there a way to use 2) <% %> to send output to the view?
Or is it against the rules to have <% %> tags that span multiple lines of ruby code at all?
<%= code %> will print to the the output the result of the inner code. <% %> won't print anything, it just evaluates the inner code.
That's why the first example doesn't work. On the second example you expect the puts to print the tweets, but puts doesn't print on the same buffer... (you'll see the tweets printed on the rails console instead).
On 3rd and 4th example you are printing the collection as an object (#meme.tweets.each returns an Enumerable and ERb call #to_s on that) and not the code inside the block.
The 5th form is correct. That's what you'll normally do.
The 6th form is in some way correct too. There you are iterating a collection, calling #to_s on each element and then collecting them on a new array, that gets printed to the output (but you are printing an array of strings, not just one big string).
you can get a similar result with #join. (It returns a string created by converting each element of the array to a string)
<%= #meme.tweets.join %>
<% %> are used when you do not want the Ruby code you're executing to output anything. The <%= %> tags are used when you want to output something. This is why your example using <%= %> and tweet.to_s works as intended.
If you don't specify which attribute you want to output, then yes, puts will display the whole object. If for example, you had a message attribute on your tweet object, writing tweet.message (inside of a <%= %>, of course) would output just the message attribute of that tweet.
The direct answer is the concat function, eg:
Hi, my name is <% concat("Shelvacu") %>.
which is the same as
Hi, my name is <%= "Shelvacu" %>.
Which both output Hi, my name is Shelvacu.
Think of it like this: An erb template is parsed, transformed into valid ruby code, and then that ruby code is run*. Everything that is not inside <% ... %> is converted to concat("..."), <% statement %> is converted to statement, and <%= statement %> is converted to concat(statement.to_s).
So when ERB sees
1 + 2 = <%= 1 + 2 %>
<% puts "hello" %>
<% #meme.tweets.each do |tweet| %>
<%= tweet %>
<% end %>
that code is then translated to*
concat("1 + 2 = ")
concat((1 + 2).to_s)
concat("\n\n")
puts "hello"
concat("\n\n")
#meme.tweets.each do |tweet|
concat(tweet.to_s)
end
* This is an oversimplification, ERB does much more so that errors point the right line, statements don't merge with eachother in unexpected ways, and I didn't even mention <%- ... %>. However, this should be a decent mental model for understanding whats happening when you write code in ERB.

Ruby How to display message if include? statement is true or false

I'm very new to Ruby and am attempting to display one of two messages based on whether certain words are included in an array. My current controller contains the following:
#cookie = ["gluten", "sugar", "dairy", "chocolate"]
And my view contains this:
<%= #cookie.include?"gluten" %>
The above returns 'true' and prints on the page just fine. However, nothing gets printed on the page when trying either of the following methods. The page renders fine with no errors, but no messages:
<%= puts "Sorry" if #cookie.include?"gluten" %>
and
<%=
if #cookie.include?("gluten")
puts "Sorry, you cannot eat this."
else
puts "You have the greenlight."
end
%>
I'm hoping that I'm creating a very simple mistake in syntax or am misunderstanding the usage of the include? function.
looking at the ruby it appears to be sound, http://rubyfiddle.com/riddles/d6798.
Must be rails error so try
<% if #cookie.include?("gluten") %>
<%= "Sorry, you cannot eat this." %>
<% else %>
<%= "You have the greenlight." %>
<% end %>
If you want it all in one erb statement, you would do something like this:
Don't use "puts". The "<%=" is already doing a 'to_s' and will output the value to the response body. You may have seen the results show up in your logs if you used 'puts'.
Also - for erb, the <% ... %> syntax, that is for logic, often an 'each' or 'if' state, the <%= %> is for writing to the screen. Most of the time it is the attribute of a ruby object like <%= user.name %>

.find() returns hash-symbols!

I have this in one of my /views/ files:
<%= Result.find(:all) %>
Result is a model. This works fine in the console but it returns ['#,'#] in the view. It has recognised that I have two results but its not displaying the results. Any ideas why?
It's not a hash that is being returned, it is the concatenated string representation you are seeing.
<%= %> is the same as puts in the console. Example:
> puts User.all
#<User:0x00000102f98550>
...
If you want to see all the attributes you need to use inspect. Example:
> puts User.all.inspect
[#<User id: 2, email: "ga...
So:
<%= Result.find(:all).inspect %>
Still not going to be pretty output though, I guess you are doing this for debugging.
Or if you want to watch each of all the Results you just should do
<% Result.find(:all) do |result| %>
<%= result.your_result_attribute %>
<% end %>
Assuming you are using Rails < 3
The reason why you are getting a # is because the next character is a <, your browser is
interpreting that as a HTML element as such if you want to quickly see what that is, wrap it in a h()
i.e.
<%= h(Result.find(:all).inspect) %>
Use or debugger to debug or logger.debug to output it in your development.log.
What you are doing here is Result.find(:all).to_s because <%= %> will do a .to_s
To debug this properly:
<% logger.debug "Result.find(:all): #{Result.find(:all).inspect}" %>

Rails - Easy way to display all fields in view

OK I'm sure I'm missing something here, but please forgive me I'm new to Rails.
Is there some way in Rails to display all the fields for an object rather than specifying each?
In my show.html template rather than going
<p>Name: <%=h #user.full_name %></p>
<p>Email: <%=h #user.email %></p>
I just want a oneliner to do this without having to type out each of the 15 or so fields I have.
Its an admin page so its fine if all the fields are shown (id, created_at, etc.)
If this was PHP it would take me about 5 secs using foreach, but I've googled (on the wrong things obviously) for an hour with no luck.
Thanks!
Something like
<% for attribute in #user.attributes.keys %>
<p><%= attribute.humanize %> <%= #user.attributes[attribute].to_s %></p>
<% end %>
could do the trick.
Matt
I suppose you want to display all attributes of a row from database table which is defined as ActiveRecord model. You can use class method column_names (every ActiveRecord model has it), which returns names of table columns in an array.
<%= User.column_names.collect { |col_name| "#{col_name.capitalize}: <p>#{#user[col_name]}</p>" }.join("\n") %>
<%= debug #user %>
simple way to show the object... that is what I usually use anyway!
#user.attributes.each{|key, value| puts "#{key} : #{value}"}
This is the snippet I used to blacklist some attributes I didn't want to show...
controller (user_controller.rb)
def show
keys_blacklist = %W(user_id name) #these are the fields to hide
#user_showlist = #user.attributes.except(*keys_blacklist)
end
view (show.html.erb):
<!-- language: ruby --><% for attribute in #user_showlist.keys %>
<b><%= attribute.humanize %></b>
<%= #user.attributes[attribute].to_s %>
<!-- language: ruby --><% end %>
You can also use instead:
#user_showlist = #user.attributes.slice(*keys_whitelist)
in order to display a whilelist of properties.
If you are using haml and want to loop through the attributes on for example a user object in a view:
- for attribute in #user.attributes.keys
%p
= attribute.humanize
= #user.attributes[attribute].to_s

Resources