Use roles in your rails models for mass assignment

Warning : This article was written a while ago, my views may have changed and this may not be relevant anymore.


As you probably know, with ActiveRecord (more exactly ActiveModel), you can whitelist some fields of your models so they are safe to be mass-assigned from a form.

Sometimes, you want some fields to be alterable by normal users, and other fields to be alterable by admins.

What I did in this case for a long time was to use slice on the params hash or create a if / else statement if the user is admin then individually assign each field.

ActiveModel provide us a much better way to to this.

Let’s assume you have a User model :

class User < ActiveRecord::Base

  attr_accessible :bio

  def role
    self.admin ? :admin : :default
  end
end

You can mass assign the bio field. There is also a role method that will tell us if the user is an admin or a default user.

Now imagine you want your admin users to be able to update other fields, for example, the login field.

Thanks to ActiveModel, we can do that with roles using the as option.

class User < ActiveRecord::Base
  attr_accessible :bio, :as => [:default, :admin]
  attr_accessible :login, :as => [:admin]

  def role
    self.admin ? :admin : :default
  end
end

Now, it’s easy to update the attributes of your model :

user.update_attributes(params[:user], :as => @current_user.role)

Only the fields accessible by the role of the current user will be updated, magic !

Since this features come in the ActiveModel interface, it also work for Mongoid and other ActiveModel based ORMs, priceless.

 
18
Kudos
 
18
Kudos

Now read this

Add some regular ruby code in your rails migrations

Warning : This article was written a while ago, my views may have changed and this may not be relevant anymore. For long, I’ve used rails migrations only as a way to update my database schema, no more. Today, I had to do a more complex... Continue →