@robertogds Avatar

17 Notes

HowTo backbone.js using rails 3

Backbone.js is a very interesting piece of software created by Jeremy Ashkenas  that “supplies structure to JavaScript-heavy applications by providing modelswith key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface”.

This is a tutorial on how to change the Backbone.js example Todo List application by Jérôme Gravel-Niquet for using a Rails 3 backend to persist the model with mysql database.

This is tested with ruby 1.9.2 and rails 3.0.3

Get the backbone source from github

$ git clone https://github.com/documentcloud/backbone.git

its creates a backbone directory with the sources inside.

Create a new rails app

$ rails new todoapp --database=mysql
$ cd todoapp
$ bundle install

We need copy the necessary files from the backbone example todos folder:

$ cp ../backbone/examples/todos/index.html ./public/
$ cp ../backbone/examples/todos/todos.js ./public/javascripts/
$ cp ../backbone/examples/todos/todos.css ./public/stylesheets/
$ cp ../backbone/examples/todos/destroy.png ./public/stylesheets/
$ cp ../backbone/backbone.js ./public/javascripts/
$ cp ../backbone/test/vendor/json2.js ./public/javascripts/
$ cp ../backbone/test/vendor/jquery-1.5.js ./public/javascripts/
$ cp ../backbone/test/vendor/underscore-1.1.4.js ./public/javascripts/

By default your database configuration will be: user= root pass= <empty> you can change this editing:

$ vim config/database.yml

You can check everything is ok creating the database:

$ rake db:create

Next its time to generate Todo scaffold and migrate database:

$ rails generate scaffold Todo content:text order:integer done:boolean
$ rake db:migrate

Now we are going to change the generated controller by one with rest interface:

$ vim app/controllers/todos_controller.rb


class TodosController < ApplicationController

  def index

     render :json => Todo.all

   end

   def show

     render :json => Todo.find(params[:id])

   end

   def create

     todo = Todo.create! params

     render :json => todo

   end

   def update

     todo = Todo.find(params[:id])

     todo.update_attributes! params

     render :json => todo

   end

   def destroy

    todo = Todo.find(params[:id])

    todo.destroy

    render :json => todo

  end

end

And change the model definition to json

$ vim app/models/todo.rb
class Todo < ActiveRecord::Base
attr_accessible :content, :order, :done

  def to_json(options = {})
    super(options.merge(:only => [ :id, :content, :order, :done ]))
  end
end


As you can read in the backbone documentation Rails’ default to_json implementation includes a model’s attributes under a namespace. To disable this behavior for seamless Backbone integration, set:

$ vim config/initializers/new_rails_defaults.rb
ActiveRecord::Base.include_root_in_json = false

Finally we need to fix the routes in index.html and delete the backbone-localstorage.js reference.

$ vim public/index.html
  <head>
    <title>Backbone Demo: Todos</title>
    <link href="stylesheets/todos.css" media="all" rel="stylesheet" type="text/css"/>
    <script src="javascripts/json2.js"></script>
    <script src="javascripts/vendor/jquery-1.5.js"></script>
    <script src="javascripts/vendor/underscore-1.1.4.js"></script>
    <script src="javascripts/backbone.js"></script>
    <script src="javascripts/todos.js"></script>
  </head>

Instead of extend backbone.sync we are going to provide a url function to the model:

$ vim public/javascripts/todos.js
// Todo Model

window.Todo = Backbone.Model.extend({

  defaults: {
      content: "empty todo...",
      done: false
  },

  initialize: function() {
    if (!this.get("content")) {
      this.set({"content": this.EMPTY});
    }
  },

  toggle: function() {
    this.save({done: !this.get("done")});
  },

  url : function() {
    return this.id ? '/todos/' + this.id : '/todos';
  },

  clear: function() {
    this.destroy();
    this.view.remove();
  }

});

Also comment the following line because we don’t use localStorage.

  //localStorage: new Store("todos"),

And specify a url function for the collection:

 url :'/todos',

Our last step is starting rails and check if everything is ok:

$ rails server

Replies

Likes

  1. hitac reblogged this from robertogds
  2. threetreeslight reblogged this from robertogds
  3. pixel67 reblogged this from robertogds
  4. abidzar reblogged this from robertogds
  5. yuku reblogged this from robertogds
  6. lefthandme reblogged this from robertogds
  7. devape reblogged this from robertogds
  8. rusalex reblogged this from robertogds
  9. robertogds posted this

 

Reblogs