2012-02-24 86 views
2

我使用rails作为backbone.js站点的服务器端,因此我不断地来回传递Rails对象。Rails无法为ID集中分配受保护的属性created_at

我注意到在返回轨道错误WARNING: Can't mass-assign protected attributes: id, created_at, updated_at

当然,我觉得这是奇怪,因为我从来没有包括这些领域 我的JSON看起来还算正常,据我可以告诉

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

回答

7

您的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和一个调用返回的值。这并不理想,但它可以在紧要关头完成工作。

+0

但是更新始终需要返回的id,但不会更新。我认为这是我最关心的问题。如果我不发送时间戳,他们将不会返回,但我需要发送该ID。我想这就是为什么我很困惑。我可以看到导轨如何“保护我”,但我想知道为什么我在这个场合看到这一点。 – pedalpete 2012-02-24 19:31:50

+0

真棒,感谢您的更新@ salt.racer,它使我清楚。我没有对这个模型做一个平静的更新,我没有意识到,直到你的评论。现在我可以选择宁静,也可以理解为什么我会得到这个回应。 – pedalpete 2012-02-24 23:44:14

+0

只是一个后续行动 - 我遇到了同样的问题,并好奇什么是“最好”的解决方案,在我的情况下,我也删除了更新ID ...但还有一堆其他值我返回嵌入式属性或方法返回(如计算标签)...所以它们也不能更新。有没有一个轨道公约来处理这更干净? – MBHNYC 2013-05-14 16:12:21

3

这些列默认的质量分配和保护不能手动设置。但是,你可以通过定义一个方法来覆盖此行为:

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

这将允许你手动分配created_atupdated_at

+0

感谢赛义德,我不想超过他们,我想知道什么可能会导致Rails认为我这样做?有任何想法吗? – pedalpete 2012-02-24 15:49:14

+0

事实上,timestamps(created_at,updated_at)和id列自动填充到ActiveRecord中,如果您为它们发送值,那么您就是批量分配。 – 2012-02-24 17:11:49