Hey all,
I'm learning rails and am trying to put together a generic ACL check for all models. I've been able to sucessfully implement it as a method for all models by decorating ActiveRecord::Base. But when I try to do the "rails way" of creating an association (and thereby taking advantage of the ORM), I don't get very far...
Here is the code:
class ActiveRecord::Base
has_many(:permissions) named_scope(:acl_check, lambda do |user_id, method| { :include => :permission, :conditions => [ ["permissions.user_id=?", user_id], ["permissions.method=?", method], ["permissions.classname=?", self.class.name] ] } end)
# Conducts a permission check for the entire class. def self.check_acl(user_id, method)
# Perform the permission check by User. permission_check = Permission.find_by_user_id_and_instance_id_and_classname_and_method (user_id, nil, self.class.name, method) if(permission_check) # If the row exists, we generate a hit. return(true) end
# Perform the permission check by Role.
# Otherwise, the permissions check was a miss. return(false)
end
# Conducts a permission check for the current instance. def check_acl?(user_id, method)
# Perform the permission check by User. permission_check = Permission.find_by_user_id_and_instance_id_and_classname_and_method (user_id, self.id, self.class.name, method) if(permission_check) # If the row exists, we generate a hit. return(true) end
# Perform the permission check by Role.
# Otherwise, the permissions check was a miss. return(false)
end
end
Currently, calling check_acl on either an instance of a model or the model class itself functions as expected. But attempting to call acl_check (my named_scope), just results in a method not found.
At the very least I'd like to know why this isn't working and if at all possible, I'd like to hear some ideas on how I can make this work. I've heard about using modules, but I'd like to not have to include a source file in each model. Ideally doing it the object- oriented way would make me happier
But again, I'd love to hear details on why ActiveRecord isn't making this happen....