In my application I have a course model that belongs to three other models: user, subject, and student_level (they include has many in model descriptions).
To be able to create a course, I declared foreign keys for two models in course model as 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
This is my _fields.html.slim file for creating a course:
= 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
And this is my new method in courses_controller.rb
#GET /courses/new
def new
@course = current_user.courses.new
# @subjects = Subject.all
# @student_levels = StudentLevel.all
end
Above code shows that I am mass-assigning subject and student level attributes.
What is bothering me, is that in Hartl's Ruby on Rails Tutorial for version 3.2 (for example, p. 536, listing 10.7) these foreign keys should be protected. And there is an example for protected foreign key assignment.
Right now everything works fine. Also, my config/application.rb contains config.active_record.whitelist_attributes = true
Right now if I remove subject_id and student_level_id from attr_accessible (so they become protected), the application gives
ActiveModel::MassAssignmentSecurity::Error in CoursesController#create
Can't mass-assign protected attributes: subject_id, student_level_id
My question: what is the best practice when creating an entity with two foreign keys, is there a way to create/edit without exposing foreign keys as attr_accessible for mass-assignment?
Thank you very much!
UPDATE:
#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
By looking at the code of your course form my _fields.html.slim
, it looks like you are taking subject_id, student_level_id
from user only through select box
, so they should be accessible.
What should be protected is : say for example, you have Institue
model and course
belongs to an Institue
and you have a foreign_key
as institute_id
, then this institute_id
should be protected.
Other Example which I can give you is, say
Project
belongs_to User
and User
has many projects
and you have a foreign key user_id
in projects
table :
then while creating a project you should do something like :
#This will create a new project object with user_id set as id of current_user
current_user.projects.new
Now to create a project object with params :
current_user.projects.new(params[:project])
I am not sure that, their is any way to create a object with two protected attributes but definitely in your case the attributes subject_id, student_level_id
should not be protected.