diff --git a/lib/aasm/persistence/active_record_persistence.rb b/lib/aasm/persistence/active_record_persistence.rb index 54f00047..68db3797 100644 --- a/lib/aasm/persistence/active_record_persistence.rb +++ b/lib/aasm/persistence/active_record_persistence.rb @@ -117,9 +117,15 @@ def aasm_enum(name=:default) def aasm_column_looks_like_enum(name=:default) column_name = self.class.aasm(name).attribute_name.to_s - column = self.class.columns_hash[column_name] - raise NoMethodError.new("undefined method '#{column_name}' for #{self.class}") if column.nil? - column.type == :integer + + # required for rails -v < 6 + column_name = self.class.attribute_alias(column_name) if self.class.attribute_alias?(column_name) + + attr_type = self.type_for_attribute(column_name) + + raise NoMethodError.new("undefined method '#{column_name}' for #{self.class}") if attr_type.nil? || attr_type.type.nil? + + attr_type.type == :integer end def aasm_guess_enum_method(name=:default) diff --git a/spec/database.rb b/spec/database.rb index 482754b4..c1a1ecdf 100644 --- a/spec/database.rb +++ b/spec/database.rb @@ -1,5 +1,5 @@ ActiveRecord::Migration.suppress_messages do - %w{gates multiple_gates readers writers transients simples no_scopes multiple_no_scopes no_direct_assignments multiple_no_direct_assignments thieves multiple_thieves localizer_test_models persisted_states provided_and_persisted_states with_enums with_enum_without_columns multiple_with_enum_without_columns with_true_enums with_false_enums false_states multiple_with_enums multiple_with_true_enums multiple_with_false_enums multiple_false_states readme_jobs}.each do |table_name| + %w{gates multiple_gates readers writers transients simples no_scopes multiple_no_scopes no_direct_assignments multiple_no_direct_assignments thieves multiple_thieves localizer_test_models persisted_states provided_and_persisted_states with_enums with_enum_without_columns multiple_with_enum_without_columns with_true_enums with_false_enums false_states multiple_with_enums multiple_with_true_enums multiple_with_false_enums multiple_false_states readme_jobs with_aliases}.each do |table_name| ActiveRecord::Migration.create_table table_name, :force => true do |t| t.string "aasm_state" end @@ -54,4 +54,8 @@ t.string "aasm_state" t.datetime "opened_at" end + + ActiveRecord::Migration.create_table "with_aliases", :force => true do |t| + t.string "aasm_state" + end end diff --git a/spec/models/active_record/with_alias.rb b/spec/models/active_record/with_alias.rb new file mode 100644 index 00000000..e2bbddd3 --- /dev/null +++ b/spec/models/active_record/with_alias.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class WithAlias < ActiveRecord::Base + include AASM + + alias_attribute :aasm_state_alias, :aasm_state + + aasm :aasm_state_alias do + state :active, initial: true + state :inactive + + event :activate do + transitions from: :inactive, to: :active + end + + event :deactivate do + transitions from: :active, to: :inactive + end + end +end diff --git a/spec/unit/persistence/active_record_persistence_multiple_spec.rb b/spec/unit/persistence/active_record_persistence_multiple_spec.rb index dff3658a..3d51be78 100644 --- a/spec/unit/persistence/active_record_persistence_multiple_spec.rb +++ b/spec/unit/persistence/active_record_persistence_multiple_spec.rb @@ -25,15 +25,14 @@ subject { lambda{ gate.send(:aasm_column_looks_like_enum, :left) } } let(:column_name) { "value" } - let(:columns_hash) { Hash[column_name, column] } before :each do allow(gate.class.aasm(:left)).to receive(:attribute_name).and_return(column_name.to_sym) - allow(gate.class).to receive(:columns_hash).and_return(columns_hash) + allow(gate.class).to receive(:type_for_attribute).with(column_name).and_return(OpenStruct.new(type: type)) end context "when AASM column has integer type" do - let(:column) { double(Object, type: :integer) } + let(:type) { :integer } it "returns true" do expect(subject.call).to be_truthy @@ -41,7 +40,7 @@ end context "when AASM column has string type" do - let(:column) { double(Object, type: :string) } + let(:type) { :string } it "returns false" do expect(subject.call).to be_falsey @@ -120,7 +119,7 @@ # Enum are introduced from Rails 4.1, therefore enum syntax will not work on Rails <= 4.1 context "when AASM enum setting is not enabled and aasm column not present" do - let(:multiple_with_enum_without_column) {MultipleWithEnumWithoutColumn.new} + let(:multiple_with_enum_without_column) { MultipleWithEnumWithoutColumn.new } it "should raise NoMethodError for transitions" do expect{multiple_with_enum_without_column.send(:view, :left)}.to raise_error(NoMethodError, /undefined method .status./) diff --git a/spec/unit/persistence/active_record_persistence_spec.rb b/spec/unit/persistence/active_record_persistence_spec.rb index 089e378e..9b46cf0a 100644 --- a/spec/unit/persistence/active_record_persistence_spec.rb +++ b/spec/unit/persistence/active_record_persistence_spec.rb @@ -25,15 +25,14 @@ subject { lambda{ gate.send(:aasm_column_looks_like_enum) } } let(:column_name) { "value" } - let(:columns_hash) { Hash[column_name, column] } before :each do allow(gate.class.aasm).to receive(:attribute_name).and_return(column_name.to_sym) - allow(gate.class).to receive(:columns_hash).and_return(columns_hash) + allow(gate.class).to receive(:type_for_attribute).with(column_name).and_return(OpenStruct.new(type: column)) end context "when AASM column has integer type" do - let(:column) { double(Object, type: :integer) } + let(:column) { :integer } it "returns true" do expect(subject.call).to be_truthy diff --git a/spec/unit/with_alias_spec.rb b/spec/unit/with_alias_spec.rb new file mode 100644 index 00000000..89102a42 --- /dev/null +++ b/spec/unit/with_alias_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'spec_helper' + +if defined?(ActiveRecord) + require 'models/active_record/with_alias' + + load_schema + + describe 'With Allias' do + it 'should not break aasm methods' do + with_allias = WithAlias.new + expect(with_allias.aasm(:aasm_state_alias).current_state).to eq(:active) + + with_allias.deactivate! + + expect(with_allias.aasm_state).to eq('inactive') + expect(with_allias.aasm(:aasm_state_alias).current_state).to eq(:inactive) + end + end +end