lib/canard/user_model.rb in canard-0.3.2 vs lib/canard/user_model.rb in canard-0.3.4
- old
+ new
@@ -1,22 +1,35 @@
module Canard
module UserModel
-
+
# Canard applies roles to a model using the acts_as_user class method. The following User model
# will be given the :manager and :admin roles
#
# class User < ActiveRecord::Base
#
# acts_as_user :roles => :manager, :admin
#
# end
#
+ # If using Canard with a non ActiveRecord class you can still assign roles but you will need to
+ # extend the class with Canard::UserModel and add a roles_mask attribute.
+ #
+ # class User
+ #
+ # extend Canard::UserModel
+ #
+ # attr_accessor :roles_mask
+ #
+ # acts_as_user :roles => :manager, :admin
+ #
+ # end
+ #
# == Scopes
#
# Beyond applying the roles to model acts_as_user also creates some useful scopes on the User
- # model;
+ # model for ActiveRecord models;
#
# User.with_any_role(:manager, :admin)
#
# returns all the managers and admins
#
@@ -42,27 +55,40 @@
def acts_as_user(*args)
include RoleModel
options = args.extract_options!.symbolize_keys
- roles options[:roles] if options.has_key?(:roles) && column_names.include?(roles_attribute_name.to_s)
-
- valid_roles.each do |role|
- define_scopes_for_role role
+ roles options[:roles] if options.has_key?(:roles) && has_roles_mask_attribute? || has_roles_mask_accessors?
+
+ if respond_to?(:table_exists?) && table_exists?
+ valid_roles.each do |role|
+ define_scopes_for_role role
+ end
+
+ define_scope_method(:with_any_role) do |*roles|
+ where("#{role_mask_column} & :role_mask > 0", { :role_mask => mask_for(*roles) })
+ end
+
+ define_scope_method(:with_all_roles) do |*roles|
+ where("#{role_mask_column} & :role_mask = :role_mask", { :role_mask => mask_for(*roles) })
+ end
end
-
- define_scope_method(:with_any_role) do |*roles|
- where("#{role_mask_column} & :role_mask > 0", { :role_mask => mask_for(*roles) })
- end
-
- define_scope_method(:with_all_roles) do |*roles|
- where("#{role_mask_column} & :role_mask = :role_mask", { :role_mask => mask_for(*roles) })
- end
end
-
+
private
-
+
+ def has_roles_mask_accessors?
+ instance_method_names = instance_methods.map { |method_name| method_name.to_s }
+ [roles_attribute_name.to_s, "#{roles_attribute_name}="].all? do |accessor|
+ instance_method_names.include?(accessor)
+ end
+ end
+
+ def has_roles_mask_attribute?
+ respond_to?(:column_names) && column_names.include?(roles_attribute_name.to_s)
+ end
+
def define_scopes_for_role(role)
include_scope = role.to_s.pluralize
exclude_scope = "non_#{include_scope}"
define_scope_method(include_scope) do
@@ -71,19 +97,19 @@
define_scope_method(exclude_scope) do
where("#{role_mask_column} & :role_mask = 0 or #{role_mask_column} is null", { :role_mask => mask_for(role) })
end
end
-
+
def define_scope_method(method, &block)
(class << self; self end).class_eval do
define_method(method, block)
end
end
-
+
def role_mask_column
%{"#{table_name}"."#{roles_attribute_name}"}
end
end
-end
\ No newline at end of file
+end