使用 Backbone.js 更新模型Rails 不工作(未找到 PUT 路线)
在backbone.js中,我正在更新一个类别模型:
@category.save {
name : category_name,
}
这可以很好地保存并在backbone中正确更新集合。但在rails服务器端,由于路由错误,它没有保存:
Started PUT "/categories" for 127.0.0.1 at 2011-05-24 11:18:16 -0400
ActionController::RoutingError (No route matches "/categories"):
问题是rails期望PUT/update有一个包含id“/categories/:id”的url,而不仅仅是“/categories”
我通过更改来测试这一点模型 url from:
class Category extends Backbone.Model
name: 'category'
url: ->
host + '/categories'
到
class Category extends Backbone.Model
name: 'category'
url: ->
host + '/categories/2'
这工作正常。
Started PUT "/categories/2" for 127.0.0.1 at 2011-05-24 11:44:08 -0400
Processing by CategoriesController#update as JSON
Parameters: {"category"=>{"created_at"=>2010-03-14 16:30:07 -0400, "id"=>2, "name"=>"Lunchr5", "updated_at"=>2010-03-14 16:30:07 -0400, "user_id"=>1}, "api_key"=>"s1boakDIav30V6DzOFsY", "id"=>"2"}
User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`single_access_token` = 's1boakDIav30V6DzOFsY' LIMIT 1
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
SQL (0.1ms) BEGIN
AREL (0.3ms) UPDATE `users` SET `visit_count` = 11, `perishable_token` = 'YG3s4yB01FxUMdMcK8m', `updated_at` = '2011-05-24 15:44:08' WHERE `users`.`id` = 1
SQL (0.3ms) COMMIT
Option Load (0.3ms) SELECT `options`.* FROM `options` WHERE (`options`.user_id = 1) LIMIT 1
Category Load (0.2ms) SELECT `categories`.* FROM `categories` WHERE `categories`.`id` = 2 LIMIT 1
SQL (0.1ms) BEGIN
Category Load (13.1ms) SELECT `categories`.`id` FROM `categories` WHERE `categories`.`user_id` = 1 AND (`categories`.`name` = BINARY 'Lunchr5') AND (`categories`.id <> 2) LIMIT 1
AREL (0.3ms) UPDATE `categories` SET `name` = 'Lunchr5', `updated_at` = '2011-05-24 15:44:09' WHERE `categories`.`id` = 2
SQL (0.3ms) COMMIT
Redirected to http://localhost:3000/categories
Completed 302 Found in 179ms
我是否必须破解主干才能将 :id 添加到 url 中,还是我遗漏了某些内容?
In backbone.js I'm updating a category model:
@category.save {
name : category_name,
}
This saves fine and updates the collection properly in backbone. But on the rails serverside its not saving because of a routing error:
Started PUT "/categories" for 127.0.0.1 at 2011-05-24 11:18:16 -0400
ActionController::RoutingError (No route matches "/categories"):
The problem is that rails expects PUT/update to have a url including the id "/categories/:id", not just "/categories"
I tested this out by changing the model url from:
class Category extends Backbone.Model
name: 'category'
url: ->
host + '/categories'
to
class Category extends Backbone.Model
name: 'category'
url: ->
host + '/categories/2'
This works fine.
Started PUT "/categories/2" for 127.0.0.1 at 2011-05-24 11:44:08 -0400
Processing by CategoriesController#update as JSON
Parameters: {"category"=>{"created_at"=>2010-03-14 16:30:07 -0400, "id"=>2, "name"=>"Lunchr5", "updated_at"=>2010-03-14 16:30:07 -0400, "user_id"=>1}, "api_key"=>"s1boakDIav30V6DzOFsY", "id"=>"2"}
User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`single_access_token` = 's1boakDIav30V6DzOFsY' LIMIT 1
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
SQL (0.1ms) BEGIN
AREL (0.3ms) UPDATE `users` SET `visit_count` = 11, `perishable_token` = 'YG3s4yB01FxUMdMcK8m', `updated_at` = '2011-05-24 15:44:08' WHERE `users`.`id` = 1
SQL (0.3ms) COMMIT
Option Load (0.3ms) SELECT `options`.* FROM `options` WHERE (`options`.user_id = 1) LIMIT 1
Category Load (0.2ms) SELECT `categories`.* FROM `categories` WHERE `categories`.`id` = 2 LIMIT 1
SQL (0.1ms) BEGIN
Category Load (13.1ms) SELECT `categories`.`id` FROM `categories` WHERE `categories`.`user_id` = 1 AND (`categories`.`name` = BINARY 'Lunchr5') AND (`categories`.id <> 2) LIMIT 1
AREL (0.3ms) UPDATE `categories` SET `name` = 'Lunchr5', `updated_at` = '2011-05-24 15:44:09' WHERE `categories`.`id` = 2
SQL (0.3ms) COMMIT
Redirected to http://localhost:3000/categories
Completed 302 Found in 179ms
Do I have to hack backbone to add the :id to the url or am I missing something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Backbone 将根据 Model.url() 的结果确定要使用的 url。因此,如果您有
url 主干的保存方法将在服务器上尝试为: host+'/categories'
如果您没有定义 url 函数,则 url 函数的默认行为将委托给它所在的集合。因此,如果您有一个
属于类别集合的类别集合和实例,将自动使用 url host+'/categories'+'/'+category.id 保存到服务器。
现在,如果您的模型不是集合的一部分,则您无法执行此操作。您必须重写模型中的 url 函数,这样
注意这不是黑客攻击。这是正确使用主干。事实上,在backbone的未来版本中,我相信url函数不会有默认行为,并且必须为所有模型编写url函数。
Backbone will determine the url to use from the result of Model.url(). So if you have
The url backbone's save method will try on the server will be: host+'/categories'
If you do not define a url function, the default behaviour for the url function will delegate to the collection that it is in. So if you have a collection
and instance of Category that belongs to a Categories collection will automatically get use the url host+'/categories'+'/'+category.id to save to the server.
Now if your model is not part of a collection, then you can't do this. You have to override the url function in your model so something like this
Note that this is not hacking. This is using backbone correctly. In fact in future editions of backbone, I believe there will be no default behaviour of the url function, and the url function will have to be written for all Models.
在集合之外使用模型时,请提供 url 根:
http://backbonejs.org/#Model-urlRoot
When using a model outside of a collection, provide a url root:
http://backbonejs.org/#Model-urlRoot
如果您的类别存在于服务器端,那么您的类别对象应该有一个 ID,并且一切正常。从您发送的代码来看,未设置 id:
在实例化类别时添加 ID,应该没问题,否则骨干将尝试使用 POST 在后端创建类别。如果您指定 ID,它将执行 PUT。也就是说,如果您为您的对象设置一个集合。
http://documentcloud.github.com/backbone/#Sync
If your category is present on the server side, then you category object should have an ID and everything just work. From the code you sent, the id was not set:
add the ID when instantiating the category and it should be ok otherwise backbone will try to create the category on the backend with a POST. If you specify the ID it will do a PUT. That is if you setup a collection for your object.
http://documentcloud.github.com/backbone/#Sync