Class: MongoidAbility::Ability

Inherits:
Object
  • Object
show all
Includes:
CanCan::Ability
Defined in:
lib/mongoid_ability/ability.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(owner) ⇒ Ability

Returns a new instance of Ability.



33
34
35
36
37
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
63
64
65
66
67
68
69
# File 'lib/mongoid_ability/ability.rb', line 33

def initialize(owner)
  @owner = owner

  inherited_locks = owner.respond_to?(owner.class.inherit_from_relation_name) ? owner.inherit_from_relation.flat_map(&:locks_relation) : []
  inherited_locks = LocksDecorator.new(inherited_locks)

  owner_locks = owner.respond_to?(owner.class.locks_relation_name) ? owner.locks_relation : []

  self.class.subject_root_classes.each do |cls|
    cls_list = [cls] + cls.descendants
    cls_list.each do |subcls|
      # if 2 of the same, prefer open
      locks = subcls.default_locks.for_subject_type(subcls).group_by(&:group_key_for_calc).flat_map do |_, locks|
        locks.detect(&:open?) || locks.first
      end

      # if 2 of the same, prefer open
      locks += inherited_locks.for_subject_type(subcls).group_by(&:group_key_for_calc).flat_map do |_, locks|
        locks.detect(&:open?) || locks.first
      end

      # if 2 of the same, prefer open
      locks += owner_locks.for_subject_type(subcls).group_by(&:group_key_for_calc).flat_map do |_, locks|
        locks.detect(&:open?) || locks.first
      end

      selected_locks = locks.group_by(&:group_key_for_calc).flat_map do |_, locks|
        # prefer last one, i.e. the one closest to owner
        locks.last
      end

      selected_locks.sort(&Lock.sort).each do |lock|
        apply_lock_rule(lock)
      end
    end
  end
end

Instance Attribute Details

#ownerObject

Returns the value of attribute owner.



9
10
11
# File 'lib/mongoid_ability/ability.rb', line 9

def owner
  @owner
end

Class Method Details

.subject_classesObject



21
22
23
24
25
# File 'lib/mongoid_ability/ability.rb', line 21

def self.subject_classes
  ObjectSpace.each_object(Class).select do |cls|
    cls.included_modules.include?(MongoidAbility::Subject)
  end
end

.subject_root_classesObject



27
28
29
30
31
# File 'lib/mongoid_ability/ability.rb', line 27

def self.subject_root_classes
  subject_classes.reject do |cls|
    cls.superclass.included_modules.include?(MongoidAbility::Subject)
  end
end

Instance Method Details

#marshal_dumpObject



11
12
13
# File 'lib/mongoid_ability/ability.rb', line 11

def marshal_dump
  @rules
end

#marshal_load(array) ⇒ Object



15
16
17
18
19
# File 'lib/mongoid_ability/ability.rb', line 15

def marshal_load(array)
  Array(array).each do |rule|
    add_rule(rule)
  end
end

#model_adapter(model_class, action, options = {}) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/mongoid_ability/ability.rb', line 71

def model_adapter(model_class, action, options = {})
  @model_adapter ||= {}
  @model_adapter[model_class] ||= {}
  @model_adapter[model_class][action] ||= {}
  @model_adapter[model_class][action][options] ||= begin
    adapter_class = CanCan::ModelAdapters::AbstractAdapter.adapter_class(model_class)
    # include all rules that apply for descendants as well
    # so the adapter can exclude include subclasses from critieria
    rules = ([model_class] + model_class.descendants).inject([]) do |res, cls|
      res += relevant_rules_for_query(action, cls)
      res.uniq
    end
    adapter_class.new(model_class, rules, options)
  end
end