在我的应用程序中,我有一个属于其他三个模型的课程模型:用户、主题和student_level(它们在模型描述中包含许多模型(。
为了能够创建课程,我将课程模型中两个模型的外键声明为 attr_accessible。
class Course < ActiveRecord::Base
attr_accessible :objectives, :title, :subject_id, :student_level_id
belongs_to :user
belongs_to :subject
belongs_to :student_level
这是我用于创建课程的 _fields.html.slim 文件:
= render 'shared/error_messages', object: f.object
= f.label :title, t("activerecord.attributes.course.title")
= f.text_field :title
= f.label :subject_id, t("activerecord.attributes.subject.title")
= f.collection_select(:subject_id, Subject.all, :id, :title_for_select)
= f.label :student_level_id, t("activerecord.attributes.student_level.title")
= f.collection_select(:student_level_id, StudentLevel.all, :id, :title_for_select)
= f.label :objectives, t("activerecord.attributes.course.objectives")
= f.text_area :objectives, rows: 15, cols: 10
这是我在 courses_controller.rb 中的新方法
#GET /courses/new
def new
@course = current_user.courses.new
# @subjects = Subject.all
# @student_levels = StudentLevel.all
end
上面的代码显示我正在批量分配主题和学生级别的属性。
困扰我的是,在 Hartl 的 Ruby on Rails 教程 3.2 版(例如,第 536 页,清单 10.7(中,这些外键应该受到保护。还有一个受保护的外键分配示例。
现在一切正常。另外,我的配置/应用程序.rb 包含 config.active_record.白名单属性 = 真
现在,如果我从attr_accessible中删除subject_id和student_level_id(因此它们受到保护(,应用程序会给出
ActiveModel::MassAssignmentSecurity::Error in CoursesController#create
Can't mass-assign protected attributes: subject_id, student_level_id
我的问题:创建具有两个外键的实体时的最佳实践是什么,有没有办法在不公开外键的情况下创建/编辑作为批量分配attr_accessible?
谢谢!
更新:
#POST /courses/
def create
@course = current_user.courses.new(params[:course])
if @course.save
flash[:success] = t("messages.course_created")
redirect_to @course
else
render 'new'
end
end
通过查看您的课程表单的代码 my _fields.html.slim
,看起来您只能通过select box
从用户那里获取subject_id, student_level_id
,因此它们应该是可访问的。
应该保护的是:例如,你有Institue
模型,course
属于一个Institue
,你有一个foreign_key
作为institute_id
,那么这个institute_id
应该受到保护。
我可以给你的另一个例子是,比如
Project
belongs_to User
和User
有很多projects
并且您在projects
表中有一个外键user_id
:
然后在创建项目时,您应该执行以下操作:
#This will create a new project object with user_id set as id of current_user
current_user.projects.new
现在创建一个带有参数的项目对象:
current_user.projects.new(params[:project])
我不确定,有没有办法创建一个具有两个受保护属性的对象,但在您的情况下,属性subject_id, student_level_id
绝对不应该受到保护。