How to access controller's instance variable in a js.erb loaded by javascript_include_tag?

923 views
Skip to first unread message

Dmitry Suzdalev

unread,
Oct 12, 2011, 4:19:00 PM10/12/11
to rubyonra...@googlegroups.com
Hello!

In rails 3.1 app I have a controller UsersController with 'show' action.
show.html.erb contains:

<% content_for(:head) do %>
<%= javascript_include_tag 'myscript' %>
<% end %>
<p>Hello @user.name</p>

And I have this in myscript.js.erb

$jQuery(document).ready(function() {
alert(<%= @user.name %>);
});

@user is being assigned by a controller and it works just ok in show.html.erb, but in myscript.js.erb I get nil as @user and exception is thrown.

What's my error here? How to get around this? 
I googled, but all suggestions I found were about rendering partial and using :local option to pass a variable to it.
Is this the only option?
I'm asking because I suspect I miss something. It would look really natural for @user being accessible in js.erb loaded through javascript_include_tag...

radhames brito

unread,
Oct 12, 2011, 6:15:31 PM10/12/11
to rubyonra...@googlegroups.com
You render the value in the template and grab it via javascript, like this:



<%= tag :meta, :name=> 'user_name', :content=> @user.name%>


$('meta[name=user_name]').attr('content');

Dmitry Suzdalev

unread,
Oct 13, 2011, 3:29:25 AM10/13/11
to rubyonra...@googlegroups.com
And what if it is a large array of values?...
Ok to pass them as a contents of the tag?
I know I could do it with ajax request, but how do I pass this large amount of data when JS is disabled...
What I'm doing is feeding data to jQuery Flot library.
And it accepts data in place of a plot initialization, e.g.

$.plot("#placeholder", data)

so I need to somehow inline this data when initializing element => js.erb.
And then I expect to have something like:

$.plot("#placeholder", <%= @user.generate_flot_data %>)

I'm a bit new to this stuff, may ask stupid questions :)

Frederick Cheung

unread,
Oct 13, 2011, 9:24:56 AM10/13/11
to Ruby on Rails: Talk
javascript_include_tag generates a <script> tag in the output. When
the browser renders your page, it looks at that script tag and
requests myscript.js from your server. By now, the original controller
and its @user variable are long gone, you're instead looking at the
@user from a new controller, which is apparently null. one way of
dealing this might be

<% content_for :head do %>
<%= javascript_tag "var js_user_name = #{@user.name.to_json};"
<%= javascript_include_tag 'my script' %>

<% end %>

which creates a (javascript) variable called js_user_name that your
javascript would be able to use. Another option would be to pass
information about which user to pick via a query parameter (i.e.
instead of the url requested being /javascripts/myscript.js it would
be /javascripts/myscript.js?user_id=123), and have the controller that
renders the javascript set up @user accordingly.

Fred

Dmitry Suzdalev

unread,
Oct 14, 2011, 5:21:22 AM10/14/11
to rubyonra...@googlegroups.com
Thank you very much, Frederick, very useful!
I think I will go on with the first method (for starters)! :-)

Cheers,
Dmitry.
Reply all
Reply to author
Forward
0 new messages