Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js and Rails - How to handle params from Backbone models?

In a standard Rails controller, I'd create a record like this:

@user = User.new(params[:user])

This assumes that the form parameters that come in are nested.

I've been playing with Backbone.js and I noticed that by default, Backbone doesn't nest the parameters the way a normal Rails form might, which is actually something I expected. So I'm wondering what I should do...

Do I

figure out on the server-side if it's a request from Backbone by looking at accepts headers, etc and manipulate the params myself so I can keep my controller code small:

do_some_params_manipulation_with(params)
@user = User.new(params[:user])
respond_to do |format|
  if @user.save
    format.html {redirect_to users_url}
    format.json {render :json => @user.to_json }
  end
end

Or, do I instantiate the object in each branch which ends up with repeated code but might be more maintainable in the long run....

respond_to do |format|
  format.html do
    @user = User.new(params[:user])
    if @user.save
      redirect_to users_url
    end
  end

  format.json do
    @user = User.new(params) # and rely on mass-assignment protection
    if @user.save
      render :json => @user.to_json
    end
  end

end

or do I modify my Backbone.js models by overriding the .toJSON method (which I'm not entirely sure how to do because I don't know enough about Backbone.js yet) so that it nests the params?

In this situation, I have access to both sides of the app, but I am interested in what others are doing.

like image 461
Brian Hogan Avatar asked Jun 07 '11 21:06

Brian Hogan


2 Answers

It's nice when you can have the general Rails forms and Backbone forms match with respect to the root node. That's why in my last application I chose to override the Backbone models' toJSON method.

You could override the global toJSON method as Raimonds Simanovskis suggested. But even the non-DRY way approach isn't so bad. Just one line of boilerplate for each model definition:

// Depends on Underscore.js
User = Backbone.Model.extend({
  toJSON: function() {
    return { user: _.clone( this.attributes ) }
  },
  // Your other methods here
});

Edit: Corrected code sample. Sorry for the errors, I was translating from CoffeeScript to JavaScript.

like image 179
evanrmurphy Avatar answered Nov 09 '22 03:11

evanrmurphy


If you are using the backbone-rails gem, looks like you can do

var User = Backbone.Model.extend({
   paramRoot: 'user'
});

Around line 45 on github

Credit PL J and stream 7 on this link

like image 34
Phil Dudley Avatar answered Nov 09 '22 05:11

Phil Dudley