【问题标题】:Rails can't mass-assign protected attributes for id, created_atRails 无法为 id、created_at 批量分配受保护的属性
【发布时间】:2012-02-24 14:16:54
【问题描述】:

我使用 rails 作为backbone.js 站点的服务器端,因此我不断地来回传递rails 对象。

我注意到返回 WARNING: Can't mass-assign protected attributes: id, created_at, updated_at 的 rails 出现错误。

当然,我觉得这很奇怪,因为我从来不需要包含这些字段 据我所知,我的 json 看起来相当正常

参数:{"id"=>1, "updated_at"=>"2011-04-21T16:41:02Z"}, "created_at"=>"2012-02-23T21:01:02Z", "action"=> “测试更新”}

【问题讨论】:

    标签: ruby-on-rails activerecord mass-assignment


    【解决方案1】:

    您的 JSON 没有任何问题。问题是安全问题之一。默认情况下,Rails 保护某些属性不会被巨大的哈希创建或更新。这就是错误在使用术语“质量分配”时所指的内容。

    您发布的 JSON:

    Parameters: {"id"=>1, "updated_at"=>"2011-04-21T16:41:02Z"}, "created_at"=>"2012-02-23T21:01:02Z", "action"=>"test update"}
    

    包含idcreated_atupdated_at 字段。当这个 JSON 被传递到操作中并且在 model_object.update_attributes(hash_fields) 中使用哈希时,您将收到此错误。为避免此错误,您可以从哈希中删除字段并稍后分配它们,或者理想情况下,让 ActiveRecord 为您工作,这对您来说很神奇,而忽略它们。

    如果您确实需要分配它们,您可以这样做:

     model_object.id = id_variable
     model_object.created_at = created_at_variable
     model_object.updated_at = updated_at_variable
     model_object.save
    

    EDIT1(解决关于传回 id 的评论):

    如果您使用 Rails REST 模型并调用 controller/:id/action url,则无需将 ID 传回,因为该信息已嵌入在 URL 中。它可以通过params[:id] 访问,通过params[:model_name] 访问哈希(遵循Rails 模型)。

    如果你正在做一些不同的事情并且 ID 必须在被传回的 JSON 中,那么你可以简单地做id = params[:model_name][:id].delete,这将从散列中删除 id 并返回一个值称呼。这并不理想,但可以在紧要关头完成工作。

    【讨论】:

    • 但是更新总是需要返回id,而不是更新。我认为这是我最大的担忧。如果我不向主干发送时间戳,它们将不会被返回,但我需要发送 id。我想这就是我如此困惑的原因。我可以看到 rails 是如何“保护我”的,但我想知道为什么我会在这个场合看到这个。
    • 太棒了,感谢@salt.racer 的更新让我明白了。我没有对那个模型做一个平静的更新,直到你发表评论我才意识到这一点。现在我可以选择休息或不休息,并了解我收到此回复的原因。
    • 只是对此的跟进——我遇到了同样的问题,并且很好奇“最佳”解决方案是什么,在我的情况下,我也在更新时删除了 ID……但是那里是我作为嵌入属性或方法返回(如计算标签)返回的一堆其他值......所以它们也无法更新。是否有一个 Rails 约定可以更干净地处理这个问题?
    【解决方案2】:

    默认情况下,这些列受质量分配保护,无法手动设置。但是,您可以通过定义一个方法来覆盖此行为:

    def self.attributes_protected_by_default
      [] # ["created_at", "updated_at" ..other]
    end
    

    这将允许您手动分配created_atupdated_at

    【讨论】:

    • 感谢 Syed,我不想超越他们,我想知道是什么导致 Rails 认为我这样做了?有什么想法吗?
    • 时间戳(created_at、updated_at)和 id 列会自动填充到 ActiveRecord 中,如果您为它们发送值,那么您就是在批量分配。
    猜你喜欢
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    相关资源
    最近更新 更多