Define dynamic methods in a module so they can be overriden and still call super

This commit is contained in:
dwbutler 2012-08-28 14:05:09 -07:00
parent 04d0674ff1
commit f1a4a79360
2 changed files with 44 additions and 6 deletions

View file

@ -36,20 +36,25 @@ module RoleModel
def roles(*roles)
opts = roles.last.is_a?(Hash) ? roles.pop : {}
self.valid_roles = roles.flatten.map(&:to_sym)
self.define_dynamic_queries unless opts[:dynamic] == false
unless (opts[:dynamic] == false)
self.define_dynamic_queries(self.valid_roles)
end
end
# Defines dynamic queries for valid_roles:
# Defines dynamic queries for :role
# #is_<:role>?
# #<:role>?
#
# Defines new methods which call #is?(:role)
def define_dynamic_queries
valid_roles.each do |role|
["#{role}?".to_sym, "is_#{role}?".to_sym].each do |method|
define_method(method) { is? role }
def define_dynamic_queries(roles)
dynamic_module = Module.new do
roles.each do |role|
["#{role}?".to_sym, "is_#{role}?".to_sym].each do |method|
define_method(method) { is? role }
end
end
end
include dynamic_module
end
end
end

View file

@ -334,6 +334,39 @@ describe RoleModel do
lambda { model.is_foo? }.should raise_error(NoMethodError)
lambda { model.bar? }.should raise_error(NoMethodError)
end
it "should be able to override the default dynamic query methods and call super" do
klass = Class.new do
def bar?
return false
end
attr_accessor :roles_mask
attr_accessor :custom_roles_mask
include RoleModel
roles :foo, :bar, :baz
def is_baz?
return false
end
def foo?
ret = super
!ret
end
end
model = klass.new
model.roles = [:foo, :bar, :baz]
model.foo?.should be_false
model.bar?.should be_false
model.is_bar?.should be_true
model.is_baz?.should be_false
model.baz?.should be_true
end
end
context "query for multiple roles" do