Rails - Cant get gsub to work to replace string text - ruby-on-rails

I'm using the liquid gem and a wysiwyg editor for user posts. I'm trying to replace some of the content submitted before it is displayed. To do this I have tried .gsub but it isn't working at all
<% template = Liquid::Template.parse(#category.template) %>
<% render = template.render(#keys_values_hash) %>
<% content = render.gsub!('data-imgslap=', 'data-slap=') %>
<% content.html_safe %>
The content is displayed fine and it all works but the text isnt replaced from gsub
I want it to just replace one thing so I know it works. But once that works I want to replace a couple of things. How would I use gsub to replace say 'text1', 'replacement1' and 'text2', 'replacement2' and why wont it work for just one replacement like I have setup now.
The data is stored as a string and grabbed from the db if that matters.
Update
Got it working. forgot to add the equal sign on <%= on content.html_safe %>
still got the problem of having 2 gsub changes on the one string here is what I have which doesnt change any coding
<% template = Liquid::Template.parse(#category.template) %>
<% render = template.render(#keys_values_hash) %>
<%
replacements = [ ['data-imgslap=', 'src='], [' src="http://i.imgur.com/bEDR9dc.png"', ''] ]
replacements.each {|replacement| render.gsub(replacement[0], replacement[1])}
%>
<%= render.html_safe %>
Got this from another question on stackoverflow but it doesn't work for me.

Generally, don't use multi-line statements in ERB. Make it two lines. And use gsub! to change the render object.
<% replacements = [ ['data-imgslap=', 'src='], ['src="http://i.imgur.com/bEDR9dc.png"', ''] ] %>
<% replacements.each {|replacement| render.gsub!(replacement[0], replacement[1])} %>
<%= render.html_safe %>

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.

Strings not displayed right

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

Why is Rails' ERB rendering output from this template code?

I'm using Rails 3.0.3, and the following template (with a .html.erb extension):
<% "one"; "two"; capture do %>
Three
<% end %>
Is rendering as:
one
Why is this? It doesn't seem like it should render anything, since I didn't use <%=
EDIT
Since there seems to be some confusion, here is a reproduction that more closely resembles the actual template code that I'm debugging:
<% my_string = "" %>
<% my_string << capture do %>
Hello
<% end %>
<%= my_string %>
This is rendering as:
Hello Hello
Because for some reason, the captured output is being appended to my_string AND being rendered, instead of just the former.
You're using the rails capture helper but your syntax is wrong. I don't know why it's printing out one. In rails 3.4 it doesn't print out anything.
Here's the right way to use it
<% #number = capture do %>
three
<% end %>
this is some html and here is my <%= #number %>
The html that will be rendered is
this is some html and here is my three
Since your syntax is wrong I wouldn't worry about why "one" is showing up. Instead I'd focus more on using the capture helper correctly.
Edit:
Your second (edited) example is not the same as your first one. Here it is with line numbers and a slight change to the last line so you can see what's going on.
1. <% my_string = "" %>
2. <% my_string << capture do %>
3. Hello
4. <% end %>
5. before <%= my_string %> after
The result is Hello before Hello after. So line 3 is being rendered, then line 5 is being rendered with my_string containing the value Hello.
If you change it to this
<% my_string = "" %>
<% my_string = capture do %> <!-- changed << to = -->
Hello
<% end %>
before <%= my_string %> after
Then the result is before Hello after.
So what does this all mean? When you use << it's screwing up the capture method and it's rendering stuff that's inside the capture block even though normally you don't expect it to.
Basically, you can't do what you're trying to do here, at least not with your current syntax.

Ruby on Rails seems to be auto-escaping html created by link_to

Here is my code, I'm trying to display a list of links to a bboy's crews in sentence form with .to_sentence
<span class="affiliation">
<% if(#bboy.crews.count > 0)%>
<span><%= if(#bboy.crews.size > 1) then "Crew".pluralize else "Crew" end %>:</span>
<%= #bboy.crews.collect{|c| link_to c.name, c}.to_sentence %>
<% else %>
<em>Independent</em>
<% end %>
</span>
The output I get is the correct links but it displays as:
Hustle Kidz and Knuckleheads Cali
rather than:
Hustle Kidz and
Knuckleheads
Cali
with the html escaped, rather than the desired links.
Am I missing something? I've tried CGI.unescapeHTML and a few others but am getting lost...
Rails 3 now automatically escapes everything, in order to output raw HTML use this:
<%= some_string.html_safe %>
or this:
<%= raw #some_html_string %>
Thanks to macek for a hint.
For additional details: http://markconnell.co.uk/posts/2010/02/rails-3-html-escaping
You can (and should) you the raw method
<%= raw #some_html_string %>
I agree with Kleber S, you should move this into a helper, because that's a lot of logic for a view
def crews_description(crews)
if crews.empty?
content_tag('em', 'Independent')
else
label = "Crew"
label = label.pluralize if crews.size > 1
crews_links = crews.map {|crew| link_to(h(crew.name), crew)}.to_sentence
content_tag('span', label) + crews_links.html_safe
end
end
and in your view:
<span class="affiliation">
<%= crews_description(#bboy.crews)
</span>
I recommend you move this block of code to an helper and then use the .html_safe method to obtain the expected results.

Resources