Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design Patterns for a Rails 3.2 JS-heavy App

I am working on a new rails 3.2 company management app which relies heavily on JSON data (autocomplete results, calendar events, tasks, dynamic form manipulation, etc.). The backend system is already pretty solid, so we are investing in the UI part and we want to make it more webapp-like, mirroring the behaviour of other 'fat client' apps such as those from Google. To achieve this objective, what would be the best design pattern: using a MVC JS framework such as Backbone.js , thus delegating a good part of the data manipulation to the UI and interfacing with our JSON api, or working with remote JS (i.e. js.erb templates), which allows for a greater use of Ruby code?

We are already using Backbone.js very crudely in some views, but it seems like the former approach uses a lot of developer resources since JS is harder to code and we have the extra burden of mirroring some model code on the UI, while being a lot more responsive to the enduser. The latter approach allows for leaner View code at the expense of response time and, all and all, doesn't feel quite right, but it certainly is faster to develo and more flexible.

Bearing in mind that we are a small team with a lot of Rails experience and not so much in JS / Coffeescript / Backbone.js and we have a close deadline to meet, which approach would you choose? The reason I am at loss in this one is that our company prides itself in the quality of our code and adherence to modern design patterns, so I can't help but think that, despite its strong points, using remote JS feels like a 'bad shortcut', so I would really appreciate the input from you guys. Maybe I am just biased.

like image 832
marcelowiermann Avatar asked Feb 20 '12 10:02

marcelowiermann


People also ask

Is Rails still relevant 2022?

Ruby's and Ruby on Rails' Overall Popularity Although way behind main contenders, such as PHP or Python, Ruby still makes the cut for the 20 most popular programming languages list in 2022. The 2022 edition of Stack Overflow Annual Developer Survey also places RoR in a similar spot.


1 Answers

Well I can't decide for you, that depends mainly on how close is the deadline but I personnaly prefer the Backbone.js approach.

If I have to argue I can say that you will have a static and cacheable JS script and light AJAX requests (only JSON), while with the other approach you will have heavier and non-cacheable scripts download.

But above all I believe that the Backbone way is the best approach to get your code organized and maintainable.

  1. Coffeescript is awesome and very fast to learn. It simplifies a lot the JS syntax and make it fun. It worth the try. Learned in 30mn.

  2. Backbone.js is awesome and fast to learn. Using this approach will allow you to rely on events, which is far much clean than that we can do without.

    Thanks to the assets pipeline, you can split your views / models / routers class in separate files, which is very nice.

    Thanks to coffeescript you can write your backbone objects with a very clean syntax like that :

    class @MyView extends Backbone.View
      events:
        'click obj': 'handler'
      [...]
    

    With that I add in my projects a little @module helper to organize my objects into namespaces.

However, it will take you some time to find the good files organisation.

You can start with gem rails-backbone and have some generators similar to rails ones. I don't like it personnaly but I think it's a good start. It includes a Backbone.sync function adapted to rails.

Edit

Here some details about the @module helper. I include this in application.js.coffee (don't forget to require_self):

@module = (names, fn) ->
  names = names.split '.' if typeof names is 'string'
  space = @[names.shift()] ||= {}
  space.module ||= @module
  if names.length
    space.module names, fn
  else
    fn.call space

In my class files :

@module 'MyProject.Model', ->
  class @MyModel extends Backbone.Model
    [...]

(Note that @ is the coffeescript shortcut for this..)

The helper creates objects MyProject and MyProject.Model if needed (if null) and executes the given function with this bind to MyProject.Model. So you can access to your model like that from root namespace (document):

m = new MyProject.Model.MyModel

You also can imbricate the helper :

@module 'MyProject', ->
  @module 'Model', ->
    [...]

I use the following namespaces hierarchy

MyProject
  Model
  View
  Router
  Runtime (to store all runtimes objects and don't pollute the root namespace, easier for debug)
like image 114
Thomas Guillory Avatar answered Sep 20 '22 14:09

Thomas Guillory