Module: Marks::Markable::ClassMethods

Defined in:
lib/marks/markable.rb

Instance Method Summary collapse

Instance Method Details

#markable_with(*types) ⇒ Object



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
# File 'lib/marks/markable.rb', line 6

def markable_with(*types)
  has_many :incoming_marks, as: :markable, dependent: :destroy, class_name: 'Marks::Mark'

  types.each do |type|
    # just for preload_marker's result cache, which is used by marked_by?
    has_one :"#{type}_marked_flag"
  end

  class_eval do
    define_method :'markers' do |class_name, mark|
      classified_mark = mark.to_s.classify
      raise ArgumentError unless types.map { |t| t.to_s.classify }.include?(classified_mark)
      klass = class_name.to_s.classify.constantize
      klass.joins(:outgoing_marks).where('marks_marks.mark_type = ? AND markable_type = ? AND markable_id = ?', mark.to_s.classify, self.class.base_class.to_s, self)
    end

    define_method :'marked_by?' do |marker, mark|
      classified_mark = mark.to_s.classify
      raise ArgumentError unless types.map { |t| t.to_s.classify }.include?(classified_mark)
      return false unless marker

      # if preload_marker is executed, use its result
      if self.association(:"#{mark}_marked_flag").loaded?
        return self.association(:"#{mark}_marked_flag").target
      end

      klass = marker.class.table_name.classify.constantize
      klass.joins(:outgoing_marks).where('marks_marks.mark_type = ? AND markable_type = ? AND markable_id = ?', mark.to_s.classify, self.class.base_class.to_s, self).any?
    end
  end
end