Class: Approval

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/acts_as_approvable/approval.rb

Constant Summary collapse

STATES =

Enumeration of available states.

%w(pending approved rejected)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.enumerate_state(state) ⇒ Integer

Find the enumerated value for a given state.

Returns:

  • (Integer)


21
22
23
# File 'lib/acts_as_approvable/approval.rb', line 21

def self.enumerate_state(state)
  enumerate_states(state).first
end

.enumerate_states(*states) ⇒ Array

Find the enumerated values for a list of states.

Returns:

  • (Array)


29
30
31
# File 'lib/acts_as_approvable/approval.rb', line 29

def self.enumerate_states(*states)
  states.map { |name| STATES.index(name) }.compact
end

.options_for_stateObject

Build an array of states usable by Rails’ ‘#options_for_select`.



35
36
37
38
39
# File 'lib/acts_as_approvable/approval.rb', line 35

def self.options_for_state
  options = [['All', -1]]
  STATES.each_index { |x| options << [STATES[x].capitalize, x] }
  options
end

.options_for_type(with_prompt = false) ⇒ Object

Build an array of types usable by Rails’ ‘#options_for_select`.



43
44
45
46
47
# File 'lib/acts_as_approvable/approval.rb', line 43

def self.options_for_type(with_prompt = false)
  types = all(:select => 'DISTINCT(item_type)').map { |row| row.item_type }
  types.unshift(['All Types', nil]) if with_prompt
  types
end

Instance Method Details

#able_to_save?Boolean

Returns true if the approval able to be saved. This requires an unlocked approval, or an approval just leaving the ‘pending’ state.

Returns:

  • (Boolean)


101
102
103
# File 'lib/acts_as_approvable/approval.rb', line 101

def able_to_save?
  unlocked? or state_was == 'pending'
end

#approve!(force = false) ⇒ Object

Attempt to approve the record change.

Parameters:

  • force (Boolean) (defaults to: false)

    if the approval record is stale force the acceptance.

Raises:



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/acts_as_approvable/approval.rb', line 137

def approve!(force = false)
  raise ActsAsApprovable::Error::Locked if locked?
  raise ActsAsApprovable::Error::Stale if stale? and !force
  return unless run_item_callback(:before_approve)

  if update?
    data = {}
    object.each do |attr, value|
      data[attr] = value if item.attribute_names.include?(attr)
    end

    item.attributes = data
  elsif create?
    item.set_approval_state('approved')
  end

  item.save_without_approval!
  update_attributes!(:state => 'approved')
  run_item_callback(:after_approve)
end

#approved?Boolean

Returns true if the approval has been approved.

Returns:

  • (Boolean)


76
77
78
# File 'lib/acts_as_approvable/approval.rb', line 76

def approved?
  state == 'approved'
end

#create?Boolean

Returns true if this is a ‘:create` approval event.

Returns:

  • (Boolean)


127
128
129
# File 'lib/acts_as_approvable/approval.rb', line 127

def create?
  event == 'create'
end

#fresh?Boolean

Returns true if the affected item has not been updated since this approval was created.

Returns:

  • (Boolean)


115
116
117
# File 'lib/acts_as_approvable/approval.rb', line 115

def fresh?
  not stale?
end

#locked?Boolean

Returns true if the approval has been approved or rejected.

Returns:

  • (Boolean)


88
89
90
# File 'lib/acts_as_approvable/approval.rb', line 88

def locked?
  approved? or rejected?
end

#pending?Boolean

Returns true if the approval is still pending.

Returns:

  • (Boolean)


70
71
72
# File 'lib/acts_as_approvable/approval.rb', line 70

def pending?
  state == 'pending'
end

#reject!(reason = nil) ⇒ Object

Attempt to reject the record change.

Parameters:

  • reason (String) (defaults to: nil)

    a reason for rejecting the change.

Raises:



163
164
165
166
167
168
169
170
171
172
# File 'lib/acts_as_approvable/approval.rb', line 163

def reject!(reason = nil)
  raise ActsAsApprovable::Error::Locked if locked?
  return unless run_item_callback(:before_reject)

  item.set_approval_state('rejected') if create?

  item.save_without_approval!
  update_attributes!(:state => 'rejected', :reason => reason)
  run_item_callback(:after_reject)
end

#rejected?Boolean

Returns true if the approval has been rejected.

Returns:

  • (Boolean)


82
83
84
# File 'lib/acts_as_approvable/approval.rb', line 82

def rejected?
  state == 'rejected'
end

#reset!Object

Force the approval back into a ‘pending’ state. Only valid for :create events.

Raises:



178
179
180
181
182
183
184
185
186
# File 'lib/acts_as_approvable/approval.rb', line 178

def reset!
  raise ActsAsApprovable::Error::InvalidTransition.new(state, 'pending', self) unless create?

  item.set_approval_state('pending')
  item.save_without_approval!

  state_will_change! # Force an update to the record
  update_attributes!(:state => 'rejected')
end

#stale?Boolean

Returns true if the affected item has been updated since this approval was created.

Returns:

  • (Boolean)


108
109
110
# File 'lib/acts_as_approvable/approval.rb', line 108

def stale?
  unlocked? and item.has_attribute?(:updated_at) and updated_at < item.updated_at
end

#stateObject

Get the current state of the approval. Converts from integer via STATES constant.



51
52
53
# File 'lib/acts_as_approvable/approval.rb', line 51

def state
  STATES[(read_attribute(:state) || 0)]
end

#state=(state) ⇒ Object

Set the state of the approval. Converts from string to integer via STATES constant.



63
64
65
66
# File 'lib/acts_as_approvable/approval.rb', line 63

def state=(state)
  state = self.class.enumerate_state(state) if state.is_a?(String)
  write_attribute(:state, state)
end

#state_wasObject

Get the previous state of the approval. Converts from integer via STATES constant.



57
58
59
# File 'lib/acts_as_approvable/approval.rb', line 57

def state_was
  STATES[(changed_attributes[:state] || 0)]
end

#unlocked?Boolean

Returns true if the approval has not been approved or rejected.

Returns:

  • (Boolean)


94
95
96
# File 'lib/acts_as_approvable/approval.rb', line 94

def unlocked?
  not locked?
end

#update?Boolean

Returns true if this is an ‘:update` approval event.

Returns:

  • (Boolean)


121
122
123
# File 'lib/acts_as_approvable/approval.rb', line 121

def update?
  event == 'update'
end