Module: ReviewAndApprove::ModelAdditions

Defined in:
lib/review_and_approve/model_additions.rb

Instance Method Summary collapse

Instance Method Details

#review_and_approve(*args) ⇒ Object



3
4
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
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
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/review_and_approve/model_additions.rb', line 3

def review_and_approve(*args)
  # Extracting options:
  # 1. methods to cache - option :by, default value [:as_json]
  # 2. attribute to track as published - option :field, default value :publish
  field = :publish
  methods = [:as_json]
  key_proc = Proc.new{|obj, method| "ReviewAndApprove_#{obj.class.name}_#{obj.id}_#{method}"}
  args.each do |arg|
    if arg.is_a? Hash
      if !arg[:by].nil?
        methods = arg[:by]
      end
      if !arg[:field].nil?
        field = arg[:field]
      end
      if !arg[:cache_key].nil?
        key_proc = arg[:cache_key]
      end
    end
  end

  # define the field as an attribute on the model
  attr_accessor field

  # identifier on the class that it has been set up with review_and_approve
  send(:define_singleton_method, :_using_rev_app?) do
    true
  end

  after_save :review_and_approve_after_save_callback

  send(:define_method, :review_and_approve_after_save_callback) do |publish = false|
    published = self.send(field) || publish
    #If we are publishing the record
    if published and (published==true or published=="true" or published=="on" or self.send(field).to_i>0 rescue false) #in case the field gets set to "0" and "1"
      methods.each do |method|
        # Refresh published cache
        cr = CacheRecord.find_or_initialize_by_key("#{key_proc.call(self, method)}_published_version")
        cr.cache_data =  self.send(method)
        cr.save
      end
    end

    methods.each do |method|
      #Refresh current value cache
      cr = CacheRecord.find_or_initialize_by_key("#{key_proc.call(self, method)}_current_version")
      cr.cache_data = self.send(method)
      cr.save
    end

    true
  end

  send(:define_method, :published_version) do |method_name|
    CacheRecord.find_by_key("#{key_proc.call(self, method_name)}_published_version").cache_data rescue nil
  end

  send(:define_method, :current_version) do |method_name|
    CacheRecord.find_by_key("#{key_proc.call(self, method_name)}_current_version").cache_data rescue nil
  end

  send(:define_method, :mass_assignment_authorizer) do |role = :default|
    # force add the :publish attribute into attr_accessible
    super(role) + [field]
  end

  # Check if a record has been published before.
  send(:define_method, :published?) do
    CacheRecord.where("key = '#{key_proc.call(self, methods.first)}_published_version'").count>0
  end

  validates_each field do |record, attr, value|
    able = Thread.current[:reviewAndApprove_current_ability].try(:can?, :publish, record)
    # if user can not publish the record, create an error.
    if !able and value and (value==true or value=="true" or value=="on" or value.to_i>0 rescue false)
      record.errors[attr] << "can not be marked as true by this user"
    end
  end
end