0

I've only been working with Rails for a few months now so I may be missing something obvious, but if an attribute is protected from mass assignment by attr_accessible, or attr_protected, how do you set that attribute when you first create a record? (And do it in a way that is still secure.)


For example:

Say I'm working on an application that keeps track of different procedures and processes that employees in a company have been trained on.

As part of this application, I have three models: User, Course, and TrainingClass. User represents employees, Course represents different things employees can be trained on, and TrainingClass represents a specific class in which employees will be trained on a course.

The TrainingClass has a belongs_to relationship with both the Course model (because a class is basically just a specific instance of a course) and the User model (because the class has a single instructor, who is the user who creates the TrainingClass). Similarly, the Course and User models both have a has_many relationship with the TrainingClass model.

Based on that information, how would I go about creating a new record for TrainingClass?

I could say:

course.training_classes.build(user_id: user.id)

or

user.training_classes.build(course_id: course.id)

But wouldn't that be mass assignment on the user_id or course_id attributes?

What would be the best way to do this while still keeping the application secure?

Ajedi32
  • 45,670
  • 22
  • 127
  • 172

1 Answers1

3

Read about Mass Assignment Security, specifically roles.

You could have

class TraningClass < ActiveRecord::Base
  attr_accessible .....
  attr_accessible ....., :user_id, as: :create
end

Where ...... is your list of other attributes you want accessible for mass assignment. Then when you call build, you'll pass that role

course.training_classes.build({user_id: user.id}, as: :create)

Repeat similarly for your other models. The default role will be used (the first one) unless you specify the :create role when calling build, create!, etc...

deefour
  • 34,974
  • 7
  • 97
  • 90
  • Thanks, that's just what I was looking for. One minor thing though; in your example `user_id: user.id` needs to be enclosed in braces {}, otherwise Rails interprets `as` as just another parameter to be assigned to the `TrainingClass`. (I'd make the correction myself, but apparently StackOverflow won't let me make edits less than 6 characters long? What's with that?) – Ajedi32 Jul 12 '12 at 15:16