Rails: access controller instance variable in CoffeeScript or JavaScript asset file
a couple of ways I have done this in the past
put the data in hidden fields, access the data in js/coffee
# single value<%= hidden_field_tag "foo_name", @foo.name, { :id => "foo-name" } %>$('#foo-name').val();# when the 'value' has multiple attributes<%= hidden_field_tag "foo", @foo.id, { :id => "foo", "data-first-name" => @foo.first_name, "data-last-name" => @foo.last_name } %>$foo = $('#foo')console.log $foo.val()console.log $foo.data("firstName")console.log $foo.data("lastName")
another option: load data into js data structure in erb, access it from js/coffee
<% content_for(:head) do %> <script> window.App = window.App || {}; window.App.Data = window.App.Data || {}; window.App.Data.fooList = [ <% @list.each do |foo| %> <%= foo.to_json %>, <% end %> ]; </script><% end %># coffeefor foo in window.App.Data.fooList console.log "#{foo.id}, #{foo.first_name} #{foo.last_name}"
I am not a big fan of constructing javascript data from ruby in erb like this, something about it just feels wrong - it can be effective though
and another option: make an ajax call and get the data on-demand from the server
I am also interested in other ideas and approaches
There is a really nice rail cast and quite recent (feb. 2012) about this specific topic:#324 Passing Data to JavaScript
It shows 3 ways: a script tag, a data attribute, and the Gon gem.I think house covered all the available techniques. I would only mention that using an AJAX call is best used when you have a large volume of data, dynamic data or combination of both.
Rather than use a hidden field I chose to add a data attribute to the container div which jquery can pick up.
<div class="searchResults" data-query="<%= @q %>"></div>
then the jquery to access it
url: "/search/get_results?search[q]=" + $(".searchResults").data("query") + "&page=" + p
I feel this is the cleanest way to pass data to javascript. After having found no way to pass a variable to a coffee script file with the rails asset pipeline from a controller. This is the method I now use. Can't wait till someone does set up the controller way with rails that will be the best.