1
0
Fork 0
mirror of https://github.com/aasm/aasm synced 2023-03-27 23:22:41 -04:00

Move creation of scopes to persistence adapaters

- extend the classes with create_scope method
- avoid expensive "klass.ancestors.map" checks
- ORM-specific code is in one place
This commit is contained in:
Christian Seiler 2016-02-27 12:06:36 +01:00
parent 24b1ad99ec
commit a33315698f
4 changed files with 41 additions and 44 deletions

View file

@ -31,6 +31,7 @@ module AASM
def self.included(base) def self.included(base)
base.send(:include, AASM::Persistence::Base) base.send(:include, AASM::Persistence::Base)
base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods) base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods)
base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods
base.after_initialize do base.after_initialize do
aasm_ensure_initial_state aasm_ensure_initial_state
@ -40,6 +41,23 @@ module AASM
base.validate :aasm_validate_states base.validate :aasm_validate_states
end end
module ClassMethods
def aasm_create_scope(state_machine_name, scope_name)
conditions = {
table_name => { aasm(state_machine_name).attribute_name => scope_name.to_s }
}
if ActiveRecord::VERSION::MAJOR >= 3
class_eval do
scope scope_name, lambda { where(conditions) }
end
else
class_eval do
named_scope scope_name, :conditions => conditions
end
end
end
end
module InstanceMethods module InstanceMethods
# Writes <tt>state</tt> to the state column and persists it to the database # Writes <tt>state</tt> to the state column and persists it to the database

View file

@ -63,53 +63,11 @@ module AASM
private private
def create_scope?(name) def create_scope?(name)
@state_machine.config.create_scopes && !@klass.respond_to?(name) @state_machine.config.create_scopes && !@klass.respond_to?(name) && @klass.respond_to?(:aasm_create_scope)
end end
def create_scope(name) def create_scope(name)
if ancestors_include?("ActiveRecord::Base") @klass.aasm_create_scope(@name, name)
create_for_active_record(name)
elsif ancestors_include?("Mongoid::Document")
create_for_mongoid(name)
elsif ancestors_include?("MongoMapper::Document")
create_for_mongomapper(name)
end
end
def ancestors_include?(class_name)
@klass.ancestors.map { |klass| klass.to_s }.include?(class_name)
end
def create_for_active_record(name)
conditions = {
@klass.table_name => { @klass.aasm(@name).attribute_name => name.to_s }
}
if ActiveRecord::VERSION::MAJOR >= 3
@klass.class_eval do
scope name, lambda { where(conditions) }
end
else
@klass.class_eval do
named_scope name, :conditions => conditions
end
end
end
def create_for_mongoid(name)
klass = @klass
state_machine_name = @name
scope_options = lambda {
klass.send(
:where,
{ klass.aasm(state_machine_name).attribute_name.to_sym => name.to_s }
)
}
@klass.send(:scope, name, scope_options)
end
def create_for_mongomapper(name)
conditions = { @klass.aasm(@name).attribute_name.to_sym => name.to_s }
@klass.scope(name, lambda { @klass.where(conditions) })
end end
end # Base end # Base

View file

@ -33,6 +33,7 @@ module AASM
def self.included(base) def self.included(base)
base.send(:include, AASM::Persistence::Base) base.send(:include, AASM::Persistence::Base)
base.send(:include, AASM::Persistence::MongoMapperPersistence::InstanceMethods) base.send(:include, AASM::Persistence::MongoMapperPersistence::InstanceMethods)
base.extend AASM::Persistence::MongoMapperPersistence::ClassMethods
base.before_create :aasm_ensure_initial_state base.before_create :aasm_ensure_initial_state
@ -40,6 +41,13 @@ module AASM
base.validate :aasm_validate_states base.validate :aasm_validate_states
end end
module ClassMethods
def aasm_create_scope(state_machine_name, scope_name)
conditions = { aasm(state_machine_name).attribute_name.to_sym => scope_name.to_s }
scope(scope_name, lambda { where(conditions) })
end
end
module InstanceMethods module InstanceMethods
# Writes <tt>state</tt> to the state column and persists it to the database # Writes <tt>state</tt> to the state column and persists it to the database

View file

@ -33,10 +33,23 @@ module AASM
def self.included(base) def self.included(base)
base.send(:include, AASM::Persistence::Base) base.send(:include, AASM::Persistence::Base)
base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods) base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)
base.extend AASM::Persistence::MongoidPersistence::ClassMethods
base.after_initialize :aasm_ensure_initial_state base.after_initialize :aasm_ensure_initial_state
end end
module ClassMethods
def aasm_create_scope(state_machine_name, scope_name)
scope_options = lambda {
send(
:where,
{ aasm(state_machine_name).attribute_name.to_sym => scope_name.to_s }
)
}
send(:scope, scope_name, scope_options)
end
end
module InstanceMethods module InstanceMethods
# Writes <tt>state</tt> to the state column and persists it to the database # Writes <tt>state</tt> to the state column and persists it to the database