Tomoko Yamaguchi
Tomoko Yamaguchi

Reputation: 497

How to avoid embedding javascript in views/show

I have a Rails app that uses javascript (Backbone) to show user specific data on each users profile page /views/users/show.html.erb. I do this by passing <%= @user.id %> as a data parameter to Backbone's fetch function, however, the only way I know how to get the <%= @user.id %> into Backbone's fetch function is by embedding the javascript in each views/users/show.html.erb page, which therefore allows Backbone to load different user specific info for each views/users/show.html.erb page. Although this works, it seems like the wrong way to do it, as I have read that I should not embed javascript like this. Furthermore, I am going to have to do it a lot, because I wish to display a lot of different kinds of data, more than you see below. So the show.html.erb page will be filled with javascript to make the app work the way I wish.

Question: how might I get @user.id into Backbone's fetch function for each user's show page without embedding javascript in the way that I've done. In the comments, someone suggest I use app/assets/javascripts/user.js, but I don't know how to get <%= @user.id %> into that file. @user.id is readily available in show.html.erb

<script type='text/javascript'> 
    $(document).ready(function() {

       app.collections.awardCollection.fetch({ data: $.param({ user_id: <%= @user.id %> }) }).complete(function(){ 
      app.views.awardCollection = new app.Views.awardCollection({ collection : app.collections.awardCollection});
       app.views.awardCollection.render() 
    });
           });
  </script>

Upvotes: 1

Views: 143

Answers (2)

rorra
rorra

Reputation: 9693

In order to understand how the views works, is that you can add as many extensions to a view as you want, and they will be parsed by the right library.

If you create a view like

my_view.haml.erb

It will be first parsed with ruby (erb), and then with haml, and will end in a html page.

You can create many views for js, usually you want to archive that when you do ajax, so you can end having a js view like:

my_view.js.erb

First ruby will be parsed (all the <% %> tags), that will end as plain text, and then the server will serve the .js file. But that's usually a common task for ajax.

If you have to render a html page where you want to put some js and you need some ruby code on it, what I usually do is to put the data in the html content with a hidden div.

You can put in any view (even on your layout if you want it to be globally available), something like:

<div id="user_id" style="display: none;"><%= @user.id %></div>

And then on a js (or coffeescript or whatever) you can just check the content of that div:

<script type="text/javascript">
  var user_id = $("#user_id").html();
</div>

that's really useful when you want to debug or create tests for your js files, since its plain js and won't throw syntax errors.

Upvotes: 2

pablomarti
pablomarti

Reputation: 2107

I see the comment of Luís Ramalho and Gon is a good option, but I recommend use the following approaches:

  1. If the from the variable is not going to change, print it with <%= %> under .js.erb files located in app/assets/javascripts (note that it will be cached until you restart your app)
  2. If you need server variables the best way is to use Ajax
  3. You can define functions on .js files on app/assets/javascripts and call those functions from the views
  4. If you really don't want any Javascript code in the view, you can create the functions on a .js on app/assets/javascripts (corresponding to the view, for order), and use events and/or store the variables in hidden fields (or even use the data attribute from HTML5)

Upvotes: 2

Related Questions