ActiveRecord 3.1 - Mass-Assignment Roles

Hi,

I think it’s awesome that Rails 3.1 introduces the attribute accessible roles/permissions:

class User

attr_accessible :name, :as => :admin

end

User.create(params[:user], :as => :admin)

But would it be possible to make this a chained function as was done with find, where and

scopes from Rails 2.x to Rails 3.0? Here’s a little more on the topic. Maybe ARel could be

leveraged to do this?

I can see that there might be conflicts with user defined scopes, but isn’t chaining functions

just so much more elegant than passing multiple hash parameters to a function?

Thanks,

Pan

I'm curious whether you can define the :as option as a list of roles? All the examples I have seen only has the :as linked to the single role :admin. How would I use this with a roles system?

Say I had a #current_user_roles method available from my Controller or whatever.

def update   Project.update_attributes(params[:project], :as => current_user_roles) end

One possible DSL tweak allow something like this:

as_role current_user_roles do |role|   role.update_attributes_of(Project).with params[:project]   role.create(Project).with params[:project] end

Here the #as_role should return some object that has the methods #update_attributes #create and so on and a method/reader for the roles to apply the role permission check.

I'm curious whether you can define the :as option as a list of roles? All the examples I have seen only has the :as linked to the single role :admin.

In short, no, it's not a 'role' in the sense that you mean here, rather the name of a parameter filter to use. Your app itself will need to have it's own logic and semantics for figuring out which filter to use based on your own business rules.

I understand that it is just a simple symbol match and you have to write your own business logic behind it: If we imagine we have a role system along these lines, where a #the_current_user method returns a User instance that has a #roles_list method that returns an array of roles (as Symbols) Then we could imagine something like the following logic to make it a bit more convenient and logic DSL like (IMO):

    # as_role current_user_roles do |role|     # role.update_attributes_of(Project).with params[:project]     # role.create(Project).with params[:project]     # end     def as_role role, &block       yield RoleModelManager.new role     end

    def as_roles *roles, &block       yield RoleModelManager.new roles.flatten     end

    class RoleModelManager       attr_accessor :roles

      def initialize *roles         @roles = roles.flatten       end

      def update_attributes_of model_clazz         AttributesUpdater.new model_clazz       end

      def create model_clazz         ModelCreator.new model_clazz       end

      class AttributesUpdater         attr_accessor :clazz

        def initialize clazz           @clazz = clazz         end

        def with attributes = {}           clazz.constantize.update_attributes(attributes.merge(:as => roles))         end       end

      class ModelCreator         attr_accessor :clazz

        def initialize clazz           @clazz = clazz         end

        def with attributes = {}           clazz.constantize.create(attributes.merge(:as => roles))         end       end     end

    def current_roles       the_current_user.roles_list     end

What do you think? My question is, if the current logic relating to the :as option can evaluate according to an array of symbols (using #include? fx) ?

What do you think? My question is, if the current logic relating to the :as option can evaluate according to an array of symbols (using #include? fx) ?

What would multiple values mean for :as? Any of these? all of these? There's no valid / sane semantics for merging black and white lists together.

You'll probably always have to do that yourself, this isn't intended for the use case you seem to have.