I'm using PrivatePub and I'm experiencing some weird behaviour here. Before going through the details please note that I'm using Ruby 1.9.3
and Rails 3.2.2
.
Let's say I have TestsController
:
class TestsController < ApplicationController
def index
end
def create
respond_to do |format|
format.js
end
end
end
And tests/index.html.erb
:
<h1>Test</h1>
<%= content_for :footer do %>
<%= subscribe_to tests_path %>
<% end %>
And tests/create.js.erb
:
<% publish_to tests_path do %>
alert("Working fine");
if (false) {alert("This never run");};
if (false) {<% puts "*"*100 %>};
<% end %>
Simple and straight forward. Now my problem is that whenever I run create
action, for some reason <% puts "*"*100 %>
always run (even when I made if(false) statement).
I know I can just use ruby if
and then should work fine, something like:
<% if false %>
<% puts "*"*100 %>
<% end %>
But still I want to do some clients side validation (as for example to check that a div exist and then render some partials accordingly) like:
if ($("#chat").length){
$("#chat").append("<%= j render(@messages) %>");
}
But seems <%= j render(@messages) %>
will be rendered all the time.
How can I tackle this problem and use client side if statement and ruby template code inside? At the moment It seems that anything inside <%%>
would be triggered and I don't want this behaviour.
puts "*"*100
is always printed because during the processing of your js.erb
file, all Ruby code inside the file is executed.
The JavaScript code is only executed when it runs in your browser, so the if (false)
statement has no effect during the ERB processing of the file.
So, this has nothing to do with the PrivatePub gem, but it is because you are mixing JS and Ruby code.
For your last (chat) code example, try render_to_string
, but perhaps that's not enough because the @messages
variable is empty during the compilation of the JS file.
I would like to add that mixing JS and Ruby can lead to some headaches. Sometimes it's better to set data-attributes on your HTML elements with Ruby/ERB in your view file, and then let the JS code read and use the value of those data-attributes. That way you don't have to use Ruby code inside your JS code.