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.