diff --git a/README.md b/README.md index 7e58020..69305cd 100644 --- a/README.md +++ b/README.md @@ -293,15 +293,23 @@ class Job < ActiveRecord::Base running: 99 } - aasm :column => :state, :enum => :states do + aasm :column => :state, :enum => true do state :sleeping, :initial => true state :running end end ``` -You need to pass the name of the method which provides access to the -enumeration mapping as a value of ```enum```. +You can explicitly pass the name of the method which provides access +to the enumeration mapping as a value of ```enum```, or you can simply +set it to true. In the latter case AASM will try to use pluralized +column name to access possible enum states. + +Furthermore, if your column has integer type (which is normally the +case when you ), you can omit ```:enum``` setting - AASM auto-detects +this situation and enabled enum support. If anything goes wrong, you +can disable enum functionali and fall back to default behavior by +setting ```:enum => false```. ### Sequel diff --git a/lib/aasm/persistence/active_record_persistence.rb b/lib/aasm/persistence/active_record_persistence.rb index 501687e..66d15ce 100644 --- a/lib/aasm/persistence/active_record_persistence.rb +++ b/lib/aasm/persistence/active_record_persistence.rb @@ -119,7 +119,20 @@ module AASM private def aasm_enum - AASM::StateMachine[self.class].config.enum + case AASM::StateMachine[self.class].config.enum + when false then nil + when true then aasm_guess_enum_method + when nil then aasm_guess_enum_method if aasm_column_looks_like_enum + else AASM::StateMachine[self.class].config.enum + end + end + + def aasm_column_looks_like_enum + self.class.columns_hash[self.class.aasm_column.to_s].type == :integer + end + + def aasm_guess_enum_method + self.class.aasm_column.to_s.pluralize.to_sym end def aasm_skipping_validations diff --git a/spec/unit/persistence/active_record_persistence_spec.rb b/spec/unit/persistence/active_record_persistence_spec.rb index 6869374..b0a85e4 100644 --- a/spec/unit/persistence/active_record_persistence_spec.rb +++ b/spec/unit/persistence/active_record_persistence_spec.rb @@ -23,6 +23,115 @@ describe "instance methods" do expect(gate).to respond_to(:aasm_write_state_without_persistence) end + describe "aasm_column_looks_like_enum" do + subject { lambda{ gate.send(:aasm_column_looks_like_enum) } } + + let(:column_name) { "value" } + let(:columns_hash) { Hash[column_name, column] } + + before :each do + gate.class.stub(:aasm_column).and_return(column_name.to_sym) + gate.class.stub(:columns_hash).and_return(columns_hash) + end + + context "when AASM column has integer type" do + let(:column) { double(Object, type: :integer) } + + it "returns true" do + expect(subject.call).to be_true + end + end + + context "when AASM column has string type" do + let(:column) { double(Object, type: :string) } + + it "returns false" do + expect(subject.call).to be_false + end + end + end + + describe "aasm_guess_enum_method" do + subject { lambda{ gate.send(:aasm_guess_enum_method) } } + + before :each do + gate.class.stub(:aasm_column).and_return(:value) + end + + it "pluralizes AASM column name" do + expect(subject.call).to eq :values + end + end + + describe "aasm_enum" do + subject { lambda{ gate.send(:aasm_enum) } } + + context "when AASM enum setting contains an explicit enum method name" do + let(:enum) { :test } + + before :each do + AASM::StateMachine[Gate].config.stub(:enum).and_return(enum) + end + + it "returns whatever value was set in AASM config" do + expect(subject.call).to eq enum + end + end + + context "when AASM enum setting is simply set to true" do + before :each do + AASM::StateMachine[Gate].config.stub(:enum).and_return(true) + Gate.stub(:aasm_column).and_return(:value) + gate.stub(:aasm_guess_enum_method).and_return(:values) + end + + it "infers enum method name from pluralized column name" do + expect(subject.call).to eq :values + expect(gate).to have_received :aasm_guess_enum_method + end + end + + context "when AASM enum setting is explicitly disabled" do + before :each do + AASM::StateMachine[Gate].config.stub(:enum).and_return(false) + end + + it "returns nil" do + expect(subject.call).to be_nil + end + end + + context "when AASM enum setting is not enabled" do + before :each do + AASM::StateMachine[Gate].config.stub(:enum).and_return(nil) + Gate.stub(:aasm_column).and_return(:value) + end + + context "when AASM column looks like enum" do + before :each do + gate.stub(:aasm_column_looks_like_enum).and_return(true) + gate.stub(:aasm_guess_enum_method).and_return(:values) + end + + it "infers enum method name from pluralized column name" do + expect(subject.call).to eq :values + expect(gate).to have_received :aasm_guess_enum_method + end + end + + context "when AASM column doesn't look like enum'" do + before :each do + gate.stub(:aasm_column_looks_like_enum) + .and_return(false) + end + + it "returns nil, as we're not using enum" do + expect(subject.call).to be_nil + end + end + end + end + context "when AASM is configured to use enum" do let(:state_sym) { :running } let(:state_code) { 2 }