Module: MongoidAbility::Subject::ClassMethods

Defined in:
lib/mongoid_ability/subject.rb

Overview

=====================================================================

Instance Method Summary collapse

Instance Method Details

#accessible_by(ability, action = :read) ⇒ Object

TODO: obviously this could be cleaner



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/mongoid_ability/subject.rb', line 46

def accessible_by ability, action=:read
  cr = self.criteria

  return cr unless ability.user.present?

  supercls = self.ancestors_with_default_locks.last || self
  subject_classes = [supercls].concat(supercls.subclasses)

  subject_classes.each do |cls|

    roles_id_locks = ability.user.roles_relation.collect{ |role| role.locks_relation.for_subject_type(cls.to_s).id_locks.for_action(action) }.flatten
    user_id_locks = ability.user.locks_relation.for_subject_type(cls.to_s).id_locks.for_action(action)

    closed_roles_id_locks = roles_id_locks.to_a.select(&:closed?)
    open_roles_id_locks = roles_id_locks.to_a.select(&:open?)

    closed_user_id_locks = user_id_locks.to_a.select(&:closed?)
    open_user_id_locks = user_id_locks.to_a.select(&:open?)

    if ability.can?(action, cls)
      excluded_ids = []

      id_locks = closed_roles_id_locks.
        reject{ |cl| open_roles_id_locks.any?{ |ol| ol.subject_id == cl.subject_id } }.
        reject{ |cl| open_user_id_locks.any?{ |ol| ol.subject_id == cl.subject_id } }

      id_locks += closed_user_id_locks
      
      excluded_ids << id_locks.map(&:subject_id)

      cr = cr.or(_type: cls.to_s, :_id.nin => excluded_ids.flatten)
    else
      included_ids = []

      id_locks = open_roles_id_locks
      id_locks += open_user_id_locks

      included_ids << id_locks.map(&:subject_id)

      cr = cr.or(_type: cls.to_s, :_id.in => included_ids.flatten)
    end
  end

  cr
end

#ancestors_with_default_locks ⇒ Object



39
40
41
# File 'lib/mongoid_ability/subject.rb', line 39

def ancestors_with_default_locks
  self_and_ancestors_with_default_locks - [self]
end

#default_lock(action, outcome) ⇒ Object



21
22
23
# File 'lib/mongoid_ability/subject.rb', line 21

def default_lock action, outcome
  default_locks << lock_class_name.constantize.new(subject_type: self, action: action, outcome: outcome)
end

#default_locks ⇒ Object



13
14
15
# File 'lib/mongoid_ability/subject.rb', line 13

def default_locks
  @default_locks ||= []
end

#default_locks=(val) ⇒ Object



17
18
19
# File 'lib/mongoid_ability/subject.rb', line 17

def default_locks= val
  @default_locks = val
end

#lock_class_name ⇒ Object

override if needed return for example 'MyLock'



29
30
31
# File 'lib/mongoid_ability/subject.rb', line 29

def lock_class_name
  Object.subclasses.detect{ |cls| cls < MongoidAbility::Lock }.name
end

#self_and_ancestors_with_default_locks ⇒ Object




35
36
37
# File 'lib/mongoid_ability/subject.rb', line 35

def self_and_ancestors_with_default_locks
  self.ancestors.select{ |a| a.is_a?(Class) && a.respond_to?(:default_locks) }
end