ruby-on-railsfayerjsprivate-pub

How can I mix inline ruby code with my client side RJS?


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.


Solution

  • 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.