Error saving Backbone.js model with Rails

I have a collection and a Backbone.js model for a project object:

window.Project = Backbone.Model.extend(); window.Projects = Backbone.Collection.extend({ model: Project, url: '/projects' }); 

I installed a rail controller to respond to the Backbone.js collection:

 class ProjectsController < ApplicationController def index render :json => Project.all end def create project = Project.create! params render :json => project end end 

The index works fine and I get a list of projects in my web application. The problem is that if I try to create a model in the project collection, I get a 500 error from the server.

The error message on the server is as follows:

 Started POST "/projects" for 127.0.0.1 at 2011-08-21 08:27:56 +0100 Processing by ProjectsController#create as JSON Parameters: {"title"=>"another test"} Completed 500 Internal Server Error in 16ms ActiveRecord::UnknownAttributeError (unknown attribute: action): app/controllers/projects_controller.rb:8:in `create' 

I'm not sure what unknown attribute: action means.

For information, I set projects_controller as resources :projects . I also set the rails to ActiveRecord::Base.include_root_in_json = false .

+4
source share
2 answers

Yes, Rails always adds action and controller to params . Parameters taken from ActionDispatch :: Http :: Parameters:

 def parameters @env["action_dispatch.request.parameters"] ||= begin params = request_parameters.merge(query_parameters) params.merge!(path_parameters) encode_params(params).with_indifferent_access end end 

And path_parameters :

Returns a hash with the parameters used to form the request path. The returned hash keys are strings:

 {'action' => 'my_action', 'controller' => 'my_controller'} 

So you should not do project = Project.create! params project = Project.create! params . You can go the update_attributes route:

 project = Project.new project.update_attributes params[:model_name] 

But this assumes that you have what you need in the params sub-hash, and it will not invoke your validators. The trunk will not put your default attributes, but you can override Backbone.sync and do it yourself. However, you probably want your checks to be update_attributes , which should generally be avoided.

It’s best to pull out exactly those attributes from the params that you expect there. This is even a recommended base practice :

* (In real code, never use update_attributes blindly and always assign white attributes that you can change.) *

+5
source

You can enable packaging options. Add the file to the initializer directory with:

 ActiveSupport.on_load(:action_controller) do wrap_parameters format: [:json] end 

and for json request you send params will now wrap with model name.

0
source

All Articles