Skip to content
Browse files

define missing aegis permissions in the user model so method_missing …

…is only called once per action
  • Loading branch information...
1 parent 24b2a59 commit 0089878b4628d7928dd5eb71a8be820533c5a41f @henning-koch henning-koch committed Nov 6, 2010
Showing with 51 additions and 12 deletions.
  1. +8 −11 lib/aegis/has_role.rb
  2. +1 −1 lib/aegis/loader.rb
  3. +12 −0 lib/aegis/util.rb
  4. +6 −0 spec/aegis/has_role_spec.rb
  5. +4 −0 spec/spec_helper.rb
  6. +20 −0 spec/support/spec_candy.rb
View
19 lib/aegis/has_role.rb
@@ -29,8 +29,7 @@ def has_role(options = {})
role_names.include?(role_name.to_s)
end
- prototype = respond_to?(:singleton_class) ? singleton_class : metaclass
- prototype.send :define_method, :validates_role do |*validate_options|
+ Aegis::Util.define_class_method(self, :validates_role) do |*validate_options|
validate_options = validate_options[0] || {}
send :define_method, :validate_role do
@@ -66,9 +65,11 @@ def has_role(options = {})
send :define_method, :method_missing_with_aegis_permissions do |symb, *args|
method_name = symb.to_s
if method_name =~ may_pattern
- action_path = $1
- severity = $2
- permissions.call.send("may#{severity}", self, action_path, *args)
+ action_path, severity = $1, $2
+ Aegis::Util.define_class_method(self, method_name) do |*method_args|
+ permissions.call.send("may#{severity}", self, action_path, *method_args)
+ end
+ send(method_name, *args)
else
method_missing_without_aegis_permissions(symb, *args)
end
@@ -77,12 +78,8 @@ def has_role(options = {})
alias_method_chain :method_missing, :aegis_permissions
send :define_method, :respond_to_with_aegis_permissions? do |symb, *args|
- if symb.to_s =~ may_pattern
- true
- else
- include_private = args.first.nil? ? false : args.first
- respond_to_without_aegis_permissions?(symb, include_private)
- end
+ include_private = args.first.nil? ? false : args.first
+ respond_to_without_aegis_permissions?(symb, include_private) || (symb.to_s =~ may_pattern)
end
alias_method_chain :respond_to?, :aegis_permissions
View
2 lib/aegis/loader.rb
@@ -4,7 +4,7 @@ class << self
def paths
[ 'ostruct',
-
+ 'aegis/util',
'aegis/errors',
'aegis/action',
'aegis/compiler',
View
12 lib/aegis/util.rb
@@ -0,0 +1,12 @@
+module Aegis
+ class Util
+ class << self
+
+ def define_class_method(object, method, &body)
+ prototype = object.respond_to?(:singleton_class) ? object.singleton_class : object.metaclass
+ prototype.send(:define_method, method, &body)
+ end
+
+ end
+ end
+end
View
6 spec/aegis/has_role_spec.rb
@@ -151,6 +151,12 @@
lambda { user.nonexisting_method }.should raise_error(NoMethodError)
end
+ it 'should define a missing Aegis method so that method is used directly from there on' do
+ user = @user_class.new
+ user.should_receive_and_execute(:method_missing).once
+ 2.times { user.may_do_action? }
+ end
+
end
describe 'respond_to?' do
View
4 spec/spec_helper.rb
@@ -18,3 +18,7 @@
config.use_transactional_fixtures = true
config.use_instantiated_fixtures = false
end
+
+# Requires supporting files with custom matchers and macros, etc,
+# in ./support/ and its subdirectories.
+Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
View
20 spec/support/spec_candy.rb
@@ -0,0 +1,20 @@
+# Abbreviated from http://makandra.com/notes/627-the-definitive-spec_candy-rb-rspec-helper
+
+Object.class_eval do
+
+ # a should receive that executes the expected method as usual. does not work with and_return
+ def should_receive_and_execute(method)
+ method_called = "_#{method}_called"
+
+ prototype = respond_to?(:singleton_class) ? singleton_class : metaclass
+ prototype.class_eval do
+ define_method method do |*args|
+ send(method_called, *args)
+ super
+ end
+ end
+
+ should_receive(method_called)
+ end
+
+end

0 comments on commit 0089878

Please sign in to comment.
Something went wrong with that request. Please try again.