骨干和Rails协会:避免JSON HashWithIndifferentAccess错误 [英] Backbone and Rails associations: Avoiding JSON HashWithIndifferentAccess errors
问题描述
我试图让我的骨干协会一个Rails应用程序内的工作,并试图更新现有的模型,当我有困难。具体而言,导轨引发以下错误:
在2012-01-04二时36分14秒+1000结果开始PUT/职位/ 2127.0.0.1
处理由PostsController#更新为JSON参数:
{后=> {内容=>Seconderona
created_at=>2012-01-03T10:51:09Z,ID=> 2,标题=>二测
后,的updated_at=>2012-01-03T10:51:09Z,意见=> [{}]},
ID=>2}后装载(在0.2ms)选择上岗。* FROM上岗WHERE
上岗。ID=? LIMIT 1 [ID,2]]警告:不能大规模分配
受保护的属性:在15ms的ID已完成500内部服务器错误
的ActiveRecord :: AssociationTypeMismatch(点评(#70104367824560)
预计,得了
::的ActiveSupport HashWithIndifferentAccess(#70104367278120)):结果
应用程序/控制器/ posts_controller.rb:62:在更新中的块结果
更新
应用程序/控制器/ posts_controller.rb:61:在
块引用>有几件事情:
这是触发(例如):
C = window.router.comments.models [0]
c.save({内容:更改的内容'})此外,是的,accepts_nested_attributes_for'是present在模型中。
在(违规)code以下是采取pretty多逐字从thougtbot的骨干在轨道上的电子书,并且我也试着为主干关系宝石的文档以下。双方提出这个错误。任何想法AP preciated,code以下
钢轨POST模型
类帖子< ActiveRecord的::基地
的has_many:评论 accepts_nested_attributes_for:评论 高清as_json(选项=无)
超(。(选件|| {})合并(包括:{注释:{只:[内容]}}))
结束
结束钢轨评论模型
类注释和LT; ActiveRecord的::基地
belongs_to的:岗位 accepts_nested_attributes_for:岗位 高清as_json(选项=无)
超(。(选件|| {})合并(包括:{岗位:{只:[:标题:内容]}}))
结束
结束BACKBONE POST控制器
类Backbonerelationaldemo.Models.Post扩展Backbone.Model
paramRoot:后 初始化:() - >
评论=新Backbonerelationaldemo.Collections.CommentsCollection
comments.reset(@get(意见))
@setComments(评论) setComments:(评论) - GT;
@comments =评论
类Backbonerelationaldemo.Collections.PostsCollection扩展Backbone.Collection
型号:Backbonerelationaldemo.Models.Post
网址:'/帖BACKBONE评论控制器
类Backbonerelationaldemo.Models.Comment扩展Backbone.Model
paramRoot:评论 初始化:() - >
如果(@has('后'))
@setPost(新Backbonerelationaldemo.Models.Post(@get('后'))) setPost:(后) - GT;
@post =岗位类Backbonerelationaldemo.Collections.CommentsCollection扩展Backbone.Collection
型号:Backbonerelationaldemo.Models.Comment
网址:'/评论
解决方案最近我处理了同样的问题。它实际上不是一个HashWithIndifferentAccess错误:它与如何
accepts_nested_attributes_for
预计PARAMS做在声明
accepts_nested_attributes_for:评论
,Rails将一个参数调用comments_attributes
对传入PARAMS问题是,你的JSON重新presentation从骨干来有一个
评论
属性,而不是一个comments_attributes
属性。您可以通过添加的toJSON函数来发表您的模型修复它的主干端:
#在发表你的模型
的toJSON: - >
ATTRS = _.clone(@属性)
attrs.comments_attributes = _.clone(@ attributes.comments)
删除attrs.comments
ATTRS或者你可以在你的Rails控制器处理:
#在你的帖子控制器
DEF更新
PARAMS [:comments_attributes] = params.delete(:评论)如果params.has_key? :注释
#调用update_attributes方法和其他任何你需要做的
结束希望这有助于。
I'm trying to get my backbone associations working inside a rails app , and I'm having difficulty when trying to update existing models. Specifically, Rails throws the following error:
Started PUT "/posts/2" for 127.0.0.1 at 2012-01-04 02:36:14 +1000
Processing by PostsController#update as JSON Parameters: {"post"=>{"content"=>"Seconderona", "created_at"=>"2012-01-03T10:51:09Z", "id"=>2, "title"=>"Second test post", "updated_at"=>"2012-01-03T10:51:09Z", "comments"=>[{}]}, "id"=>"2"} Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1 [["id", "2"]] WARNING: Can't mass-assign protected attributes: id Completed 500 Internal Server Error in 15msActiveRecord::AssociationTypeMismatch (Comment(#70104367824560) expected, got ActiveSupport::HashWithIndifferentAccess(#70104367278120)):
app/controllers/posts_controller.rb:62:inblock in update'
update'
app/controllers/posts_controller.rb:61:inA few things:
This is triggered on (for example):
c = window.router.comments.models[0] c.save({content: 'Changed content'})
Also, yes, 'accepts_nested_attributes_for' is present in the model.
The (offending) code below is taken pretty much verbatim from thougtbot's "backbone on rails" ebook, and I've also tried following the documentation for the backbone-relational gem. Both raise this error. Any ideas appreciated, code below
RAILS 'POST' MODEL
class Post < ActiveRecord::Base has_many :comments accepts_nested_attributes_for :comments def as_json(options = nil) super((options || {}).merge(include: { comments: { only: [content] } } )) end end
RAILS 'COMMENT' MODEL
class Comment < ActiveRecord::Base belongs_to :post accepts_nested_attributes_for :post def as_json(options = nil) super((options || {}).merge(include: { post: { only: [:title, :content]}})) end end
BACKBONE POST CONTROLLER
class Backbonerelationaldemo.Models.Post extends Backbone.Model paramRoot: 'post' initialize: () -> comments = new Backbonerelationaldemo.Collections.CommentsCollection comments.reset(@get('comments')) @setComments(comments) setComments: (comments) -> @comments = comments class Backbonerelationaldemo.Collections.PostsCollection extends Backbone.Collection model: Backbonerelationaldemo.Models.Post url: '/posts'
BACKBONE COMMENTS CONTROLLER
class Backbonerelationaldemo.Models.Comment extends Backbone.Model paramRoot: 'comment' initialize: () -> if (@has('post')) @setPost(new Backbonerelationaldemo.Models.Post(@get('post'))) setPost: (post) -> @post = post class Backbonerelationaldemo.Collections.CommentsCollection extends Backbone.Collection model: Backbonerelationaldemo.Models.Comment url: '/comments'
解决方案I dealt with the same issue recently. It's actually not a HashWithIndifferentAccess error: it has to do with how
accepts_nested_attributes_for
expects params.When you declare
accepts_nested_attributes_for :comments
, Rails looks for a parameter callcomments_attributes
on the incoming params.The problem is that your JSON representation coming from Backbone has a
"comments"
property instead of a"comments_attributes"
property.You could fix it on the Backbone side by adding a toJSON function to your Post model:
# in your Post model toJSON: -> attrs = _.clone(@attributes) attrs.comments_attributes = _.clone(@attributes.comments) delete attrs.comments attrs
Or you could handle it in your Rails controller:
# in your Posts controller def update params[:comments_attributes] = params.delete(:comments) if params.has_key? :comments # call to update_attributes and whatever else you need to do end
Hopefully this helps.
这篇关于骨干和Rails协会:避免JSON HashWithIndifferentAccess错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!