-
Notifications
You must be signed in to change notification settings - Fork 629
/
base.rb
117 lines (110 loc) · 3.62 KB
/
base.rb
1
2
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
module AASM
module Persistence
module Base
def self.included(base) #:nodoc:
base.extend ClassMethods
end
# Returns the value of the aasm_column - called from <tt>aasm.current_state</tt>
#
# If it's a new record, and the aasm state column is blank it returns the initial state
# (example provided here for ActiveRecord, but it's true for Mongoid as well):
#
# class Foo < ActiveRecord::Base
# include AASM
# aasm :column => :status do
# state :opened
# state :closed
# end
# end
#
# foo = Foo.new
# foo.current_state # => :opened
# foo.close
# foo.current_state # => :closed
#
# foo = Foo.find(1)
# foo.current_state # => :opened
# foo.aasm_state = nil
# foo.current_state # => nil
#
# NOTE: intended to be called from an event
#
# This allows for nil aasm states - be sure to add validation to your model
def aasm_read_state
state = send(self.class.aasm_column)
if new_record?
state.blank? ? aasm.determine_state_name(self.class.aasm_initial_state) : state.to_sym
else
state.nil? ? nil : state.to_sym
end
end
module ClassMethods
# Maps to the aasm_column in the database. Defaults to "aasm_state". You can write
# (example provided here for ActiveRecord, but it's true for Mongoid as well):
#
# create_table :foos do |t|
# t.string :name
# t.string :aasm_state
# end
#
# class Foo < ActiveRecord::Base
# include AASM
# end
#
# OR:
#
# create_table :foos do |t|
# t.string :name
# t.string :status
# end
#
# class Foo < ActiveRecord::Base
# include AASM
# aasm_column :status
# end
#
# This method is both a getter and a setter
def aasm_column(column_name=nil)
if column_name
AASM::StateMachine[self].config.column = column_name.to_sym
# @aasm_column = column_name.to_sym
else
AASM::StateMachine[self].config.column ||= :aasm_state
# @aasm_column ||= :aasm_state
end
# @aasm_column
AASM::StateMachine[self].config.column
end
end # ClassMethods
end # Base
end # Persistence
class Base
# make sure to create a (named) scope for each state
def state_with_scope(name, *args)
state_without_scope(name, *args)
unless @clazz.respond_to?(name)
if @clazz.ancestors.map {|klass| klass.to_s}.include?("ActiveRecord::Base")
conditions = {"#{@clazz.table_name}.#{@clazz.aasm_column}" => name.to_s}
if ActiveRecord::VERSION::MAJOR >= 4
@clazz.class_eval do
scope name, lambda { where(conditions) }
end
elsif ActiveRecord::VERSION::MAJOR >= 3
@clazz.class_eval do
scope name, where(conditions)
end
else
@clazz.class_eval do
named_scope name, :conditions => conditions
end
end
elsif @clazz.ancestors.map {|klass| klass.to_s}.include?("Mongoid::Document")
scope_options = lambda { @clazz.send(:where, {@clazz.aasm_column.to_sym => name.to_s}) }
@clazz.send(:scope, name, scope_options)
end
end
end
alias_method :state_without_scope, :state
alias_method :state, :state_with_scope
end # Base
end # AASM