Class: AccessRules::Rules::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/access_rules/rules.rb

Direct Known Subclasses

And, Not, Or

Instance Method Summary collapse

Constructor Details

#initialize(rule_name) ⇒ Base

Creates a rule given its name. Name is a dot-separated string, eg: forum_post.forum_thread.forum.group.member where forum_post - name of initial object class forum_thread.forum.group - associations to traverse: last one is supposed to contain the rule itself. Associations may be omitted - in this case initial object should contain the rule member - name of rule. This may be a rule defined using define_rule(s) or just a name of method in rule class. If it’s a method it must accept: TODO: disregard that, now only no-arg methods work 2 arguments - user, site 1 arguments - user 0 arguments and return true/false indicating whether the rules succeeded



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/access_rules/rules.rb', line 19

def initialize( rule_name )
  @rule_name = rule_name
  elems = rule_name.split( '.' )
  klass = elems.shift.classify.constantize
  proc_or_method = elems.pop
  @associations = elems.dup
  @associations.each do |assoc|
    reflection = klass.reflect_on_association( assoc.to_sym )
    raise "No rule named #{rule_name}, failed token: #{assoc}" unless reflection
    klass = reflection.class_name.constantize
  end
  @proc = klass.rules[proc_or_method.to_sym]
  unless @proc
    @method_name = proc_or_method
    # TODO: method_defined? fails for attribute accessors
    #raise "No rule named #{rule_name}, failed token: #{@method_name}" unless klass.method_defined?( @method_name ) 
  end
end

Instance Method Details

#&(rule) ⇒ Object

AND rule



65
66
67
# File 'lib/access_rules/rules.rb', line 65

def & (rule)
  return And.new( self, rule )
end

#check(object, user, site = nil) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/access_rules/rules.rb', line 38

def check( object, user, site = nil )
  # XXX: we assume has_one or belongs_to association here
  object_to_check = @associations.inject( object ) { |obj, assoc| obj.send( assoc ) }

  if @proc
    result = @proc.call( object_to_check, user, site )
  else
    # TODO: check if object.class matches klass (from initialize)
    result = object_to_check.send( @method_name )
    # TODO: the code below fails eg. for forum.public?
    #method = object_to_check.method( @method_name )
    #result = case method.arity
    #when 0
    #  method.call
    #when 1
    #  method.call( user )
    #when 2
    #  method.call( user, site )
    #else
    #  raise "Can't use method #{@method_name} on #{object_to_check} with arity #{method.arity} for access rule #{@rule_name} (arity out of (0..2) range)"
    #end
  end
  Rails.logger.debug( "----------access rule check: #{@rule_name}: #{result}" )
  return result
end

#|(rule) ⇒ Object

OR rule



70
71
72
# File 'lib/access_rules/rules.rb', line 70

def | (rule)
  return Or.new( self, rule )
end

#~Object

NOT rule



75
76
77
# File 'lib/access_rules/rules.rb', line 75

def ~
  Not.new( @rule_name )
end