Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
274 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
module AASM | ||
module Persistence | ||
module SequelPersistence | ||
def self.included(base) | ||
base.send(:include, AASM::Persistence::Base) | ||
base.send(:include, AASM::Persistence::SequelPersistence::InstanceMethods) | ||
end | ||
|
||
module InstanceMethods | ||
def before_validation | ||
aasm_ensure_initial_state | ||
super | ||
end | ||
|
||
def before_create | ||
aasm_ensure_initial_state | ||
super | ||
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 | ||
# | ||
# class Foo < Sequel::Model | ||
# 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[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? && state.to_s.strip.empty? | ||
aasm.determine_state_name(self.class.aasm.initial_state) | ||
elsif state.nil? | ||
nil | ||
else | ||
state.to_sym | ||
end | ||
end | ||
|
||
# Ensures that if the aasm_state column is nil and the record is new | ||
# that the initial state gets populated before validation on create | ||
# | ||
# foo = Foo.new | ||
# foo.aasm_state # => nil | ||
# foo.valid? | ||
# foo.aasm_state # => "open" (where :open is the initial state) | ||
# | ||
# | ||
# foo = Foo.find(:first) | ||
# foo.aasm_state # => 1 | ||
# foo.aasm_state = nil | ||
# foo.valid? | ||
# foo.aasm_state # => nil | ||
# | ||
def aasm_ensure_initial_state | ||
aasm.enter_initial_state if | ||
send(self.class.aasm_column).to_s.strip.empty? | ||
end | ||
|
||
# Writes <tt>state</tt> to the state column and persists it to the database | ||
# | ||
# foo = Foo[1] | ||
# foo.aasm.current_state # => :opened | ||
# foo.close! | ||
# foo.aasm.current_state # => :closed | ||
# Foo[1].aasm.current_state # => :closed | ||
# | ||
# NOTE: intended to be called from an event | ||
def aasm_write_state state | ||
aasm_column = self.class.aasm_column | ||
update_ony({aasm_column => state.to_s}, aasm_column) | ||
end | ||
|
||
# Writes <tt>state</tt> to the state column, but does not persist it to the database | ||
# | ||
# foo = Foo[1] | ||
# foo.aasm.current_state # => :opened | ||
# foo.close | ||
# foo.aasm.current_state # => :closed | ||
# Foo[1].aasm.current_state # => :opened | ||
# foo.save | ||
# foo.aasm.current_state # => :closed | ||
# Foo[1].aasm.current_state # => :closed | ||
# | ||
# NOTE: intended to be called from an event | ||
def aasm_write_state_without_persistence state | ||
send("#{self.class.aasm_column}=", state.to_s) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
|
||
describe 'sequel' do | ||
begin | ||
require 'sequel' | ||
require 'logger' | ||
require 'spec_helper' | ||
|
||
before(:all) do | ||
db = Sequel.sqlite | ||
# if you want to see the statements while running the spec enable the following line | ||
# db.loggers << Logger.new($stderr) | ||
db.create_table(:models) do | ||
primary_key :id | ||
String :status | ||
end | ||
|
||
@model = Class.new(Sequel::Model(db)) do | ||
set_dataset(:models) | ||
attr_accessor :default | ||
include AASM | ||
aasm :column => :status | ||
aasm do | ||
state :alpha, :initial => true | ||
state :beta | ||
state :gamma | ||
event :release do | ||
transitions :from => [:alpha, :beta, :gamma], :to => :beta | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe "instance methods" do | ||
let(:model) {@model.new} | ||
|
||
it "should respond to aasm persistence methods" do | ||
expect(model).to respond_to(:aasm_read_state) | ||
expect(model).to respond_to(:aasm_write_state) | ||
expect(model).to respond_to(:aasm_write_state_without_persistence) | ||
end | ||
|
||
it "should return the initial state when new and the aasm field is nil" do | ||
expect(model.aasm.current_state).to eq(:alpha) | ||
end | ||
|
||
it "should return the aasm column when new and the aasm field is not nil" do | ||
model.status = "beta" | ||
expect(model.aasm.current_state).to eq(:beta) | ||
end | ||
|
||
it "should return the aasm column when not new and the aasm_column is not nil" do | ||
allow(model).to receive(:new?).and_return(false) | ||
model.status = "gamma" | ||
expect(model.aasm.current_state).to eq(:gamma) | ||
end | ||
|
||
it "should allow a nil state" do | ||
allow(model).to receive(:new?).and_return(false) | ||
model.status = nil | ||
expect(model.aasm.current_state).to be_nil | ||
end | ||
|
||
it "should call aasm_ensure_initial_state on validation before create" do | ||
expect(model).to receive(:aasm_ensure_initial_state).and_return(true) | ||
model.valid? | ||
end | ||
|
||
it "should call aasm_ensure_initial_state before create, even if skipping validations" do | ||
expect(model).to receive(:aasm_ensure_initial_state).and_return(true) | ||
model.save(:validate => false) | ||
end | ||
end | ||
|
||
describe 'subclasses' do | ||
it "should have the same states as its parent class" do | ||
expect(Class.new(@model).aasm.states).to eq(@model.aasm.states) | ||
end | ||
|
||
it "should have the same events as its parent class" do | ||
expect(Class.new(@model).aasm.events).to eq(@model.aasm.events) | ||
end | ||
|
||
it "should have the same column as its parent even for the new dsl" do | ||
expect(@model.aasm_column).to eq(:status) | ||
expect(Class.new(@model).aasm_column).to eq(:status) | ||
end | ||
end | ||
|
||
describe 'initial states' do | ||
it 'should support conditions' do | ||
@model.aasm do | ||
initial_state lambda{ |m| m.default } | ||
end | ||
|
||
expect(@model.new(:default => :beta).aasm.current_state).to eq(:beta) | ||
expect(@model.new(:default => :gamma).aasm.current_state).to eq(:gamma) | ||
end | ||
end | ||
|
||
rescue LoadError | ||
puts "Not running Sequel specs because sequel gem is not installed!!!" | ||
end | ||
end |