【问题标题】:Backbone and Rails associations: Avoiding JSON HashWithIndifferentAccess errorsBackbone 和 Rails 关联:避免 JSON HashWithIndifferentAccess 错误
【发布时间】:2012-02-01 16:39:46
【问题描述】:

我正在尝试让我的骨干关联在 rails 应用程序中工作,但在尝试更新现有模型时遇到了困难。具体来说,Rails 会抛出以下错误:

在 2012-01-04 02:36:14 +1000 开始为 127.0.0.1 放置“/posts/2”
PostsController#update 处理为 JSON 参数: {"post"=>{"content"=>"Seconderona", "created_at"=>"2012-01-03T10:51:09Z", "id"=>2, "title"=>"第二次测试 post", "updated_at"=>"2012-01-03T10:51:09Z", "cmets"=>[{}]}, "id"=>"2"} Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE “帖子”。“id”=? LIMIT 1 [["id", "2"]] 警告:不能批量分配 受保护的属性:id Completed 500 Internal Server Error in 15ms

ActiveRecord::AssociationTypeMismatch (评论(#70104367824560) 预期,得到 ActiveSupport::HashWithIndifferentAccess(#70104367278120)):
app/controllers/posts_controller.rb:62:in block in update'
app/controllers/posts_controller.rb:61:in
update'

一些事情:

这是触发的(例如):

c = window.router.comments.models[0]
c.save({content: 'Changed content'})

另外,是的,模型中存在“accepts_nested_attributes_for”。

下面的(有问题的)代码几乎一字不差地取自 thougtbot 的“backbone on rails”电子书,我还尝试遵循骨干关系 gem 的文档。两者都会引发此错误。任何想法表示赞赏,下面的代码

RAILS 'POST' 模型

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

铁路“评论”模型

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

骨干后控制器

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'

主干评论控制器

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'

【问题讨论】:

    标签: javascript ruby-on-rails json backbone.js coffeescript


    【解决方案1】:

    我最近处理了同样的问题。这实际上不是 HashWithIndifferentAccess 错误:它与 accepts_nested_attributes_for 期望参数的方式有关。

    当您声明 accepts_nested_attributes_for :comments 时,Rails 会在传入的参数上查找参数调用 comments_attributes

    问题是来自 Backbone 的 JSON 表示具有 "comments" 属性而不是 "comments_attributes" 属性。

    您可以通过向您的 Post 模型添加 toJSON 函数在 Backbone 端修复它:

    # in your Post model
    toJSON: ->
      attrs = _.clone(@attributes)
      attrs.comments_attributes = _.clone(@attributes.comments)
      delete attrs.comments
      attrs
    

    或者您可以在 Rails 控制器中处理它:

    # 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
    

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      对于那些正在谷歌搜索的人......

      虽然当前接受的答案确实有效,但以下是我解决问题的方法(非常相似,但略有不同):

      我使用的是nested form,模型嵌套了 4 层深。在呈现表单的控制器中,我需要构建表单。

      def new
        @survey = Survey.new
        3.times do
          question = @survey.questions.build
          4.times { question.answers.build }
        end
      end
      

      这允许参数包含params[:survey][:questions_attributes]。 Rails 为我重命名了参数,因为我提前通知了它。

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-24
        • 2012-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-11
        • 1970-01-01
        相关资源
        最近更新 更多