Module: MongoidAbility::Lock

Defined in:
lib/mongoid_ability/lock.rb

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/mongoid_ability/lock.rb', line 5

def self.included(base)
  base.extend ClassMethods
  base.class_eval do
    field :action, type: Symbol, default: :read
    field :outcome, type: Boolean, default: false
    field :opts, as: :options, type: Hash, default: {}

    belongs_to :subject, polymorphic: true, optional: true
    # Mongoid 7 does not support `touch: true` on polymorphic associations
    after_save -> { subject.touch if subject? }
    after_destroy -> { subject.touch if subject? }
    after_touch -> { subject.touch if subject? }

    # TODO: validate that action is defined on subject or its superclasses
    validates :action, presence: true, uniqueness: { scope: [:subject_type, :subject_id, :outcome] }
    validates :outcome, presence: true

    scope :for_action, ->(action) { where(action: action.to_sym) }

    scope :for_subject_type, ->(subject_type) { where(subject_type: subject_type.to_s) }
    scope :for_subject_types, ->(subject_types) { criteria.in(subject_type: subject_types) }

    scope :for_subject_id, ->(subject_id) {
      return where(subject_id: nil) unless subject_id.present?
      where(subject_id: BSON::ObjectId.from_string(subject_id))
    }

    scope :for_subject, ->(subject) {
      return where(subject_id: nil) unless subject.present?
      where(subject_type: subject.class.model_name, subject_id: subject.id)
    }

    scope :class_locks, -> { where(subject_id: nil) }
    scope :id_locks, -> { ne(subject_id: nil) }
  end
end