我是rails的新手,正在构建我的第一个"真实"应用程序,并努力理解如何使关系正常工作。
我有一个测验模型和图标模型。每个测验都属于一个图标,一个图标有_多个测验。(将图标视为一个类别)。
在我的"新建/编辑"测验表格上,我想要一个选择框来选择正确的图标。此刻我。。。
<%= collection_select(:quiz, :icon_id, Icon.all, :id, :title, :prompt => true) %>
在我的测验控制器中,我有。。。
def create
@icon = Icon.find(params[:quiz][:icon_id])
@quiz = @icon.quizzes.build(params[:quiz])
if @quiz.save
flash[:success] = "New quiz created successfully!"
redirect_to @quiz
else
render 'new'
end
end
当我提交表格时,我会收到
Can't mass-assign protected attributes: icon_id
我理解为icon_id的错误在模型中没有被分配为attr_accessible。
我可以让它变得可访问,因为这没有真正的安全风险,也可以在传递到构建方法之前从测试哈希中删除icon_id,但这两个选项似乎都不是正确的做法。
做这件事的正确方法是什么?
谢谢!
只需放入
attr_accessible :icon_id
在你的测验模型中。
从Ruby on rails api:attr_accessible:指定可以通过批量分配设置的模型属性的白名单。
TL;DR:Rails有一个称为批量分配的功能,这就是当你传入params[:quizz]散列时所要做的。您需要为要使用批量指定更新的任何属性指定attr_accessible。
快速历史课:
过去,默认情况下,所有属性都是可批量分配的,所以您的代码运行得很好。
几个月前,github上有一个备受关注的事件,有人能够利用这个功能,用用户[:admin]=true的效果构建一个帖子主体。这有效地为用户提供了admin访问权限,因为应用程序并没有阻止任何人设置admin=true。有一种方法可以防止这种情况,但开发人员错过了
Rails对此的回应是默认保护所有属性,迫使开发人员显式指定任何可通过批量分配更新的字段。我相信这是在3.2.3版本中。