Structuring JS Assets in Rails 3.1 (Styx)

    Asset mechanism in 3.1 greatly simplified life for large projects, but at the same time a little complicated for small ones. When using the built-in generators, the rails as before create a separate file for each controller, only now the contents of these files appear by default on absolutely all pages. If in the case of SCSS this only helps, imposing the correct structuring, then what to do with JS?

    If the project is large and you use some kind of client framework like Backbone for massive JS - great! It will load better and decide where and how to work. But what if you just need to connect a small amount of code for specific pages? That is, not even controllers, but rather actions. And it is desirable that when such pieces become more than 5, the code does not turn into spaghetti. The little Styx gem can help with this .

    Styx can not only call specific code for a specific action, but also transfer data from Ruby to it. Cooking:

    
    # Gemfile
    gem 'styx'
    # app/controllers/application_controller.rb или нужный вам controller
    class ApplicationController
      include Styx::Initializer
    end
    # app/views/application.html.erb
    <%= javascript_include_tag "application" %>
    <%= styx_initialize %>
    <%= csrf_meta_tags %>
    


    If we have a FoosController controller that we created using `rails g foos', then through our efforts we also have not only app / controllers / foos_controller.rb, but also app / assets / javascripts / foos.js.coffee. Here's what the latter should look like:

    
    # Класс называется по имени контроллера в неймспейсе Styx.Initializers.
    @Styx.Initializers.Foos =
      initialize: ->
        console.log 'Этот метод будет вызван при попадании в любой action контроллера foos сразу после парсинга тега '
      index: (data) ->
        console.log 'Этот метод будет вызван при попадании в /foos/ сразу после парсинга тега '
      show: (data) -> $ ->
        console.log 'А вот таким образом (при использовании jQuery) можно вызвать метод после загрузки страницы /foos/... (см. jQuery.ready())'
    


    Note that all methods (except the general initialize) accept the data parameter. By default, this is an empty object {}, but it can be easily replenished from the side of the ruby ​​both directly in the controller and in view:

    
    # app/controllers/foos_controller.rb
    class ApplicationController
      def index
        styx_initialize_with :foo => 'bar', :and => {:habrahabr => 'rockz!'}  
      end  
    end
    


    
    # app/views/foos/index.html.erb
    <%- styx_initialize_with :something => 'very important' %>
    


    Now we get in data:

    
    {"foo": "bar", "and": {"habrahabar": "rocks!"}, "something": "very important"}
    


    That's all it takes to call our code. Due to the fact that JS is assembled into a single file and connected as a whole, you can easily describe your repeating code in classes (namely classes, thanks to Coffee) and call them on the necessary pages using Initializers. And as a nice bonus - no more dumps of ".to_json" for transferring data to JS in your views :).

    Also popular now: