aasm 4.5.1 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/LICENSE +1 -1
- data/README.md +809 -129
- data/lib/aasm/aasm.rb +74 -37
- data/lib/aasm/base.rb +188 -41
- data/lib/aasm/configuration.rb +27 -2
- data/lib/aasm/core/event.rb +75 -47
- data/lib/aasm/core/invoker.rb +129 -0
- data/lib/aasm/core/invokers/base_invoker.rb +75 -0
- data/lib/aasm/core/invokers/class_invoker.rb +52 -0
- data/lib/aasm/core/invokers/literal_invoker.rb +49 -0
- data/lib/aasm/core/invokers/proc_invoker.rb +59 -0
- data/lib/aasm/core/state.rb +22 -13
- data/lib/aasm/core/transition.rb +30 -23
- data/lib/aasm/dsl_helper.rb +24 -22
- data/lib/aasm/errors.rb +8 -5
- data/lib/aasm/instance_base.rb +63 -15
- data/lib/aasm/localizer.rb +13 -3
- data/lib/aasm/minitest/allow_event.rb +13 -0
- data/lib/aasm/minitest/allow_transition_to.rb +13 -0
- data/lib/aasm/minitest/have_state.rb +13 -0
- data/lib/aasm/minitest/transition_from.rb +21 -0
- data/lib/aasm/minitest.rb +5 -0
- data/lib/aasm/minitest_spec.rb +15 -0
- data/lib/aasm/persistence/active_record_persistence.rb +87 -79
- data/lib/aasm/persistence/base.rb +30 -30
- data/lib/aasm/persistence/core_data_query_persistence.rb +94 -0
- data/lib/aasm/persistence/dynamoid_persistence.rb +92 -0
- data/lib/aasm/persistence/mongoid_persistence.rb +49 -35
- data/lib/aasm/persistence/no_brainer_persistence.rb +105 -0
- data/lib/aasm/persistence/orm.rb +154 -0
- data/lib/aasm/persistence/plain_persistence.rb +2 -1
- data/lib/aasm/persistence/redis_persistence.rb +112 -0
- data/lib/aasm/persistence/sequel_persistence.rb +37 -67
- data/lib/aasm/persistence.rb +20 -5
- data/lib/aasm/rspec/allow_event.rb +5 -1
- data/lib/aasm/rspec/allow_transition_to.rb +5 -1
- data/lib/aasm/rspec/transition_from.rb +8 -4
- data/lib/aasm/state_machine.rb +6 -12
- data/lib/aasm/state_machine_store.rb +76 -0
- data/lib/aasm/version.rb +1 -1
- data/lib/aasm.rb +8 -2
- data/lib/generators/aasm/aasm_generator.rb +16 -0
- data/lib/generators/aasm/orm_helpers.rb +41 -0
- data/lib/generators/active_record/aasm_generator.rb +40 -0
- data/lib/generators/active_record/templates/migration.rb +8 -0
- data/lib/generators/active_record/templates/migration_existing.rb +5 -0
- data/lib/generators/mongoid/aasm_generator.rb +28 -0
- data/lib/generators/nobrainer/aasm_generator.rb +28 -0
- data/lib/motion-aasm.rb +37 -0
- metadata +104 -259
- data/.document +0 -6
- data/.gitignore +0 -19
- data/.travis.yml +0 -37
- data/API +0 -34
- data/CHANGELOG.md +0 -272
- data/CODE_OF_CONDUCT.md +0 -13
- data/Gemfile +0 -15
- data/HOWTO +0 -12
- data/PLANNED_CHANGES.md +0 -11
- data/README_FROM_VERSION_3_TO_4.md +0 -240
- data/Rakefile +0 -26
- data/aasm.gemspec +0 -31
- data/callbacks.txt +0 -51
- data/gemfiles/rails_3.2.gemfile +0 -14
- data/gemfiles/rails_4.0.gemfile +0 -12
- data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -14
- data/gemfiles/rails_4.1.gemfile +0 -12
- data/gemfiles/rails_4.1_mongo_mapper.gemfile +0 -14
- data/gemfiles/rails_4.2.gemfile +0 -12
- data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -14
- data/gemfiles/rails_4.2_mongoid_5.gemfile +0 -12
- data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -157
- data/spec/database.rb +0 -63
- data/spec/database.yml +0 -3
- data/spec/en.yml +0 -9
- data/spec/en_deprecated_style.yml +0 -10
- data/spec/models/active_record/basic_active_record_two_state_machines_example.rb +0 -25
- data/spec/models/active_record/complex_active_record_example.rb +0 -33
- data/spec/models/active_record/derivate_new_dsl.rb +0 -7
- data/spec/models/active_record/false_state.rb +0 -35
- data/spec/models/active_record/gate.rb +0 -39
- data/spec/models/active_record/localizer_test_model.rb +0 -34
- data/spec/models/active_record/no_direct_assignment.rb +0 -21
- data/spec/models/active_record/no_scope.rb +0 -21
- data/spec/models/active_record/persisted_state.rb +0 -12
- data/spec/models/active_record/provided_and_persisted_state.rb +0 -24
- data/spec/models/active_record/reader.rb +0 -7
- data/spec/models/active_record/readme_job.rb +0 -21
- data/spec/models/active_record/simple_new_dsl.rb +0 -17
- data/spec/models/active_record/thief.rb +0 -29
- data/spec/models/active_record/transient.rb +0 -6
- data/spec/models/active_record/with_enum.rb +0 -39
- data/spec/models/active_record/with_false_enum.rb +0 -31
- data/spec/models/active_record/with_true_enum.rb +0 -39
- data/spec/models/active_record/writer.rb +0 -6
- data/spec/models/basic_two_state_machines_example.rb +0 -25
- data/spec/models/callbacks/basic.rb +0 -78
- data/spec/models/callbacks/basic_multiple.rb +0 -75
- data/spec/models/callbacks/guard_within_block.rb +0 -66
- data/spec/models/callbacks/guard_within_block_multiple.rb +0 -66
- data/spec/models/callbacks/multiple_transitions_transition_guard.rb +0 -65
- data/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb +0 -65
- data/spec/models/callbacks/private_method.rb +0 -44
- data/spec/models/callbacks/private_method_multiple.rb +0 -44
- data/spec/models/callbacks/with_args.rb +0 -61
- data/spec/models/callbacks/with_args_multiple.rb +0 -61
- data/spec/models/callbacks/with_state_arg.rb +0 -26
- data/spec/models/callbacks/with_state_arg_multiple.rb +0 -26
- data/spec/models/complex_example.rb +0 -222
- data/spec/models/conversation.rb +0 -93
- data/spec/models/default_state.rb +0 -12
- data/spec/models/double_definer.rb +0 -21
- data/spec/models/foo.rb +0 -92
- data/spec/models/foo_callback_multiple.rb +0 -45
- data/spec/models/guardian.rb +0 -48
- data/spec/models/guardian_multiple.rb +0 -48
- data/spec/models/initial_state_proc.rb +0 -31
- data/spec/models/invalid_persistor.rb +0 -31
- data/spec/models/mongo_mapper/complex_mongo_mapper_example.rb +0 -37
- data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +0 -21
- data/spec/models/mongo_mapper/simple_mongo_mapper.rb +0 -23
- data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +0 -25
- data/spec/models/mongoid/complex_mongoid_example.rb +0 -37
- data/spec/models/mongoid/no_scope_mongoid.rb +0 -21
- data/spec/models/mongoid/simple_mongoid.rb +0 -23
- data/spec/models/mongoid/simple_new_dsl_mongoid.rb +0 -25
- data/spec/models/no_initial_state.rb +0 -25
- data/spec/models/not_auto_loaded/process.rb +0 -21
- data/spec/models/parametrised_event.rb +0 -29
- data/spec/models/parametrised_event_multiple.rb +0 -29
- data/spec/models/process_with_new_dsl.rb +0 -31
- data/spec/models/provided_state.rb +0 -24
- data/spec/models/sequel/complex_sequel_example.rb +0 -45
- data/spec/models/sequel/sequel_multiple.rb +0 -25
- data/spec/models/sequel/sequel_simple.rb +0 -25
- data/spec/models/silencer.rb +0 -27
- data/spec/models/simple_example.rb +0 -15
- data/spec/models/simple_multiple_example.rb +0 -30
- data/spec/models/state_machine_with_failed_event.rb +0 -12
- data/spec/models/sub_class.rb +0 -7
- data/spec/models/sub_class_with_more_states.rb +0 -18
- data/spec/models/sub_classing.rb +0 -3
- data/spec/models/super_class.rb +0 -46
- data/spec/models/this_name_better_not_be_in_use.rb +0 -11
- data/spec/models/transactor.rb +0 -53
- data/spec/models/valid_state_name.rb +0 -23
- data/spec/models/validator.rb +0 -79
- data/spec/models/worker.rb +0 -2
- data/spec/spec_helper.rb +0 -25
- data/spec/unit/api_spec.rb +0 -77
- data/spec/unit/basic_two_state_machines_example_spec.rb +0 -10
- data/spec/unit/callback_multiple_spec.rb +0 -295
- data/spec/unit/callbacks_spec.rb +0 -296
- data/spec/unit/complex_example_spec.rb +0 -84
- data/spec/unit/complex_multiple_example_spec.rb +0 -99
- data/spec/unit/edge_cases_spec.rb +0 -16
- data/spec/unit/event_multiple_spec.rb +0 -73
- data/spec/unit/event_naming_spec.rb +0 -11
- data/spec/unit/event_spec.rb +0 -322
- data/spec/unit/guard_multiple_spec.rb +0 -60
- data/spec/unit/guard_spec.rb +0 -60
- data/spec/unit/initial_state_multiple_spec.rb +0 -15
- data/spec/unit/initial_state_spec.rb +0 -12
- data/spec/unit/inspection_multiple_spec.rb +0 -201
- data/spec/unit/inspection_spec.rb +0 -111
- data/spec/unit/localizer_spec.rb +0 -76
- data/spec/unit/memory_leak_spec.rb +0 -38
- data/spec/unit/new_dsl_spec.rb +0 -12
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +0 -573
- data/spec/unit/persistence/active_record_persistence_spec.rb +0 -552
- data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +0 -146
- data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -93
- data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +0 -127
- data/spec/unit/persistence/mongoid_persistence_spec.rb +0 -79
- data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +0 -153
- data/spec/unit/persistence/sequel_persistence_spec.rb +0 -100
- data/spec/unit/readme_spec.rb +0 -42
- data/spec/unit/reloading_spec.rb +0 -15
- data/spec/unit/rspec_matcher_spec.rb +0 -79
- data/spec/unit/simple_example_spec.rb +0 -42
- data/spec/unit/simple_multiple_example_spec.rb +0 -63
- data/spec/unit/state_spec.rb +0 -89
- data/spec/unit/subclassing_multiple_spec.rb +0 -39
- data/spec/unit/subclassing_spec.rb +0 -31
- data/spec/unit/transition_spec.rb +0 -291
| @@ -1,5 +1,4 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 1 | 
            +
            require 'aasm/persistence/orm'
         | 
| 3 2 | 
             
            module AASM
         | 
| 4 3 | 
             
              module Persistence
         | 
| 5 4 | 
             
                module ActiveRecordPersistence
         | 
| @@ -30,101 +29,115 @@ module AASM | |
| 30 29 | 
             
                  #
         | 
| 31 30 | 
             
                  def self.included(base)
         | 
| 32 31 | 
             
                    base.send(:include, AASM::Persistence::Base)
         | 
| 32 | 
            +
                    base.send(:include, AASM::Persistence::ORM)
         | 
| 33 33 | 
             
                    base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods)
         | 
| 34 | 
            +
                    base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods
         | 
| 34 35 |  | 
| 35 | 
            -
                    base.after_initialize  | 
| 36 | 
            -
                      aasm_ensure_initial_state
         | 
| 37 | 
            -
                    end
         | 
| 36 | 
            +
                    base.after_initialize :aasm_ensure_initial_state
         | 
| 38 37 |  | 
| 39 38 | 
             
                    # ensure state is in the list of states
         | 
| 40 39 | 
             
                    base.validate :aasm_validate_states
         | 
| 41 40 | 
             
                  end
         | 
| 42 41 |  | 
| 43 | 
            -
                  module  | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
                    #   foo.aasm.current_state # => :closed
         | 
| 51 | 
            -
                    #   Foo.find(1).aasm.current_state # => :closed
         | 
| 52 | 
            -
                    #
         | 
| 53 | 
            -
                    # NOTE: intended to be called from an event
         | 
| 54 | 
            -
                    def aasm_write_state(state, name=:default)
         | 
| 55 | 
            -
                      old_value = read_attribute(self.class.aasm(name).attribute_name)
         | 
| 56 | 
            -
                      aasm_write_attribute state, name
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                      success = if aasm_skipping_validations(name)
         | 
| 59 | 
            -
                        value = aasm_raw_attribute_value(state, name)
         | 
| 60 | 
            -
                        self.class.where(self.class.primary_key => self.id).update_all(self.class.aasm(name).attribute_name => value) == 1
         | 
| 42 | 
            +
                  module ClassMethods
         | 
| 43 | 
            +
                    def aasm_create_scope(state_machine_name, scope_name)
         | 
| 44 | 
            +
                      if ActiveRecord::VERSION::MAJOR >= 3
         | 
| 45 | 
            +
                        conditions = { aasm(state_machine_name).attribute_name => scope_name.to_s }
         | 
| 46 | 
            +
                        class_eval do
         | 
| 47 | 
            +
                          scope scope_name, lambda { where(table_name => conditions) }
         | 
| 48 | 
            +
                        end
         | 
| 61 49 | 
             
                      else
         | 
| 62 | 
            -
                         | 
| 50 | 
            +
                        conditions = {
         | 
| 51 | 
            +
                          table_name => { aasm(state_machine_name).attribute_name => scope_name.to_s }
         | 
| 52 | 
            +
                        }
         | 
| 53 | 
            +
                        class_eval do
         | 
| 54 | 
            +
                          named_scope scope_name, :conditions => conditions
         | 
| 55 | 
            +
                        end
         | 
| 63 56 | 
             
                      end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  module InstanceMethods
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    private
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    def aasm_execute_after_commit
         | 
| 65 | 
            +
                      begin
         | 
| 66 | 
            +
                        require 'after_commit_everywhere'
         | 
| 67 | 
            +
                        raise LoadError unless Gem::Version.new(::AfterCommitEverywhere::VERSION) >= Gem::Version.new('0.1.5')
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                        self.extend ::AfterCommitEverywhere
         | 
| 70 | 
            +
                        after_commit do
         | 
| 71 | 
            +
                          yield
         | 
| 72 | 
            +
                        end
         | 
| 73 | 
            +
                      rescue LoadError
         | 
| 74 | 
            +
                        warn <<-MSG
         | 
| 75 | 
            +
              [DEPRECATION] :after_commit AASM callback is not safe in terms of race conditions and redundant calls.
         | 
| 76 | 
            +
                            Please add `gem 'after_commit_everywhere', '~> 1.0'` to your Gemfile in order to fix that.
         | 
| 77 | 
            +
                        MSG
         | 
| 78 | 
            +
                        yield
         | 
| 67 79 | 
             
                      end
         | 
| 80 | 
            +
                    end
         | 
| 68 81 |  | 
| 69 | 
            -
             | 
| 82 | 
            +
                    def aasm_raise_invalid_record
         | 
| 83 | 
            +
                      raise ActiveRecord::RecordInvalid.new(self)
         | 
| 70 84 | 
             
                    end
         | 
| 71 85 |  | 
| 72 | 
            -
                     | 
| 73 | 
            -
             | 
| 74 | 
            -
                     | 
| 75 | 
            -
             | 
| 76 | 
            -
                     | 
| 77 | 
            -
             | 
| 78 | 
            -
                     | 
| 79 | 
            -
             | 
| 80 | 
            -
                     | 
| 81 | 
            -
             | 
| 82 | 
            -
                     | 
| 83 | 
            -
             | 
| 84 | 
            -
                    def  | 
| 85 | 
            -
                       | 
| 86 | 
            +
                    def aasm_save
         | 
| 87 | 
            +
                      self.save
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                    def aasm_update_column(attribute_name, value)
         | 
| 91 | 
            +
                      self.class.unscoped.where(self.class.primary_key => self.id).update_all(attribute_name => value) == 1
         | 
| 92 | 
            +
                    end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                    def aasm_read_attribute(name)
         | 
| 95 | 
            +
                      read_attribute(name)
         | 
| 96 | 
            +
                    end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                    def aasm_write_attribute(name, value)
         | 
| 99 | 
            +
                      write_attribute(name, value)
         | 
| 100 | 
            +
                    end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                    def aasm_transaction(requires_new, requires_lock)
         | 
| 103 | 
            +
                      self.class.transaction(:requires_new => requires_new) do
         | 
| 104 | 
            +
                        lock!(requires_lock) if requires_lock
         | 
| 105 | 
            +
                        yield
         | 
| 106 | 
            +
                      end
         | 
| 86 107 | 
             
                    end
         | 
| 87 108 |  | 
| 88 | 
            -
                  private
         | 
| 89 109 | 
             
                    def aasm_enum(name=:default)
         | 
| 90 | 
            -
                      case AASM:: | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 110 | 
            +
                      case AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
         | 
| 111 | 
            +
                      when false then nil
         | 
| 112 | 
            +
                      when true then aasm_guess_enum_method(name)
         | 
| 113 | 
            +
                      when nil then aasm_guess_enum_method(name) if aasm_column_looks_like_enum(name)
         | 
| 114 | 
            +
                      else AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
         | 
| 95 115 | 
             
                      end
         | 
| 96 116 | 
             
                    end
         | 
| 97 117 |  | 
| 98 118 | 
             
                    def aasm_column_looks_like_enum(name=:default)
         | 
| 99 | 
            -
                      self.class. | 
| 119 | 
            +
                      column_name = self.class.aasm(name).attribute_name.to_s
         | 
| 120 | 
            +
                      column = self.class.columns_hash[column_name]
         | 
| 121 | 
            +
                      raise NoMethodError.new("undefined method '#{column_name}' for #{self.class}") if column.nil?
         | 
| 122 | 
            +
                      column.type == :integer
         | 
| 100 123 | 
             
                    end
         | 
| 101 124 |  | 
| 102 125 | 
             
                    def aasm_guess_enum_method(name=:default)
         | 
| 103 126 | 
             
                      self.class.aasm(name).attribute_name.to_s.pluralize.to_sym
         | 
| 104 127 | 
             
                    end
         | 
| 105 128 |  | 
| 106 | 
            -
                    def aasm_skipping_validations(state_machine_name)
         | 
| 107 | 
            -
                      AASM::StateMachine[self.class][state_machine_name].config.skip_validation_on_save
         | 
| 108 | 
            -
                    end
         | 
| 109 | 
            -
             | 
| 110 | 
            -
                    def aasm_write_attribute(state, name=:default)
         | 
| 111 | 
            -
                      write_attribute(self.class.aasm(name).attribute_name, aasm_raw_attribute_value(state, name))
         | 
| 112 | 
            -
                    end
         | 
| 113 | 
            -
             | 
| 114 129 | 
             
                    def aasm_raw_attribute_value(state, name=:default)
         | 
| 115 130 | 
             
                      if aasm_enum(name)
         | 
| 116 131 | 
             
                        self.class.send(aasm_enum(name))[state]
         | 
| 117 132 | 
             
                      else
         | 
| 118 | 
            -
                         | 
| 133 | 
            +
                        super
         | 
| 119 134 | 
             
                      end
         | 
| 120 135 | 
             
                    end
         | 
| 121 136 |  | 
| 122 137 | 
             
                    # Ensures that if the aasm_state column is nil and the record is new
         | 
| 123 | 
            -
                    #  | 
| 138 | 
            +
                    # then the initial state gets populated after initialization
         | 
| 124 139 | 
             
                    #
         | 
| 125 140 | 
             
                    #   foo = Foo.new
         | 
| 126 | 
            -
                    #   foo.aasm_state # => nil
         | 
| 127 | 
            -
                    #   foo.valid?
         | 
| 128 141 | 
             
                    #   foo.aasm_state # => "open" (where :open is the initial state)
         | 
| 129 142 | 
             
                    #
         | 
| 130 143 | 
             
                    #
         | 
| @@ -135,39 +148,34 @@ module AASM | |
| 135 148 | 
             
                    #   foo.aasm_state # => nil
         | 
| 136 149 | 
             
                    #
         | 
| 137 150 | 
             
                    def aasm_ensure_initial_state
         | 
| 138 | 
            -
                      AASM:: | 
| 151 | 
            +
                      AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
         | 
| 139 152 | 
             
                        # checking via respond_to? does not work in Rails <= 3
         | 
| 140 153 | 
             
                        # if respond_to?(self.class.aasm(state_machine_name).attribute_name) && send(self.class.aasm(state_machine_name).attribute_name).blank? # Rails 4
         | 
| 141 | 
            -
                        if  | 
| 154 | 
            +
                        if aasm_column_is_blank?(state_machine_name)
         | 
| 142 155 | 
             
                          aasm(state_machine_name).enter_initial_state
         | 
| 143 156 | 
             
                        end
         | 
| 144 157 | 
             
                      end
         | 
| 145 158 | 
             
                    end
         | 
| 146 159 |  | 
| 147 | 
            -
                    def  | 
| 148 | 
            -
                       | 
| 149 | 
            -
             | 
| 150 | 
            -
             | 
| 151 | 
            -
                        event = self.class.aasm(state_machine_name).state_machine.events[name]
         | 
| 152 | 
            -
                        event.fire_callbacks(:after_commit, self, *args)
         | 
| 153 | 
            -
                      end
         | 
| 154 | 
            -
             | 
| 155 | 
            -
                      success
         | 
| 156 | 
            -
                    end
         | 
| 157 | 
            -
             | 
| 158 | 
            -
                    def requires_new?(state_machine_name)
         | 
| 159 | 
            -
                      AASM::StateMachine[self.class][state_machine_name].config.requires_new_transaction
         | 
| 160 | 
            +
                    def aasm_column_is_blank?(state_machine_name)
         | 
| 161 | 
            +
                      attribute_name = self.class.aasm(state_machine_name).attribute_name
         | 
| 162 | 
            +
                      attribute_names.include?(attribute_name.to_s) &&
         | 
| 163 | 
            +
                        (send(attribute_name).respond_to?(:empty?) ? !!send(attribute_name).empty? : !send(attribute_name))
         | 
| 160 164 | 
             
                    end
         | 
| 161 165 |  | 
| 162 166 | 
             
                    def aasm_validate_states
         | 
| 163 | 
            -
                      AASM:: | 
| 167 | 
            +
                      AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
         | 
| 164 168 | 
             
                        unless aasm_skipping_validations(state_machine_name)
         | 
| 165 | 
            -
                          if  | 
| 166 | 
            -
                            self.errors.add(AASM:: | 
| 169 | 
            +
                          if aasm_invalid_state?(state_machine_name)
         | 
| 170 | 
            +
                            self.errors.add(AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.column , "is invalid")
         | 
| 167 171 | 
             
                          end
         | 
| 168 172 | 
             
                        end
         | 
| 169 173 | 
             
                      end
         | 
| 170 174 | 
             
                    end
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                    def aasm_invalid_state?(state_machine_name)
         | 
| 177 | 
            +
                      aasm(state_machine_name).current_state && !aasm(state_machine_name).states.include?(aasm(state_machine_name).current_state)
         | 
| 178 | 
            +
                    end
         | 
| 171 179 | 
             
                  end # InstanceMethods
         | 
| 172 180 |  | 
| 173 181 | 
             
                end
         | 
| @@ -34,13 +34,17 @@ module AASM | |
| 34 34 | 
             
                  # This allows for nil aasm states - be sure to add validation to your model
         | 
| 35 35 | 
             
                  def aasm_read_state(name=:default)
         | 
| 36 36 | 
             
                    state = send(self.class.aasm(name).attribute_name)
         | 
| 37 | 
            -
                    if  | 
| 38 | 
            -
                       | 
| 37 | 
            +
                    if !state || state.empty?
         | 
| 38 | 
            +
                      aasm_new_record? ? aasm(name).determine_state_name(self.class.aasm(name).initial_state) : nil
         | 
| 39 39 | 
             
                    else
         | 
| 40 | 
            -
                      state. | 
| 40 | 
            +
                      state.to_sym
         | 
| 41 41 | 
             
                    end
         | 
| 42 42 | 
             
                  end
         | 
| 43 43 |  | 
| 44 | 
            +
                  def aasm_new_record?
         | 
| 45 | 
            +
                    new_record?
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 44 48 | 
             
                  module ClassMethods
         | 
| 45 49 | 
             
                    def aasm_column(attribute_name=nil)
         | 
| 46 50 | 
             
                      warn "[DEPRECATION] aasm_column is deprecated. Use aasm.attribute_name instead"
         | 
| @@ -53,37 +57,33 @@ module AASM | |
| 53 57 |  | 
| 54 58 | 
             
              class Base
         | 
| 55 59 | 
             
                # make sure to create a (named) scope for each state
         | 
| 56 | 
            -
                def state_with_scope( | 
| 57 | 
            -
                  state_without_scope( | 
| 58 | 
            -
                   | 
| 59 | 
            -
             | 
| 60 | 
            -
                    if @klass.ancestors.map {|klass| klass.to_s}.include?("ActiveRecord::Base")
         | 
| 61 | 
            -
                      conditions = {"#{@klass.table_name}.#{@klass.aasm(@name).attribute_name}" => name.to_s}
         | 
| 62 | 
            -
                      if ActiveRecord::VERSION::MAJOR >= 3
         | 
| 63 | 
            -
                        @klass.class_eval do
         | 
| 64 | 
            -
                          scope name, lambda { where(conditions) }
         | 
| 65 | 
            -
                        end
         | 
| 66 | 
            -
                      else
         | 
| 67 | 
            -
                        @klass.class_eval do
         | 
| 68 | 
            -
                          named_scope name, :conditions => conditions
         | 
| 69 | 
            -
                        end
         | 
| 70 | 
            -
                      end
         | 
| 71 | 
            -
                    elsif @klass.ancestors.map {|klass| klass.to_s}.include?("Mongoid::Document")
         | 
| 72 | 
            -
                      klass = @klass
         | 
| 73 | 
            -
                      state_machine_name = @name
         | 
| 74 | 
            -
                      scope_options = lambda {
         | 
| 75 | 
            -
                        klass.send(:where, {klass.aasm(state_machine_name).attribute_name.to_sym => name.to_s})
         | 
| 76 | 
            -
                      }
         | 
| 77 | 
            -
                      @klass.send(:scope, name, scope_options)
         | 
| 78 | 
            -
                    elsif @klass.ancestors.map {|klass| klass.to_s}.include?("MongoMapper::Document")
         | 
| 79 | 
            -
                      conditions = { @klass.aasm(@name).attribute_name.to_sym => name.to_s }
         | 
| 80 | 
            -
                      @klass.scope(name, lambda { @klass.where(conditions) })
         | 
| 81 | 
            -
                    end
         | 
| 82 | 
            -
             | 
| 60 | 
            +
                def state_with_scope(*args)
         | 
| 61 | 
            +
                  names = state_without_scope(*args)
         | 
| 62 | 
            +
                  names.each do |name|
         | 
| 63 | 
            +
                    create_scopes(name)
         | 
| 83 64 | 
             
                  end
         | 
| 84 65 | 
             
                end
         | 
| 85 66 | 
             
                alias_method :state_without_scope, :state
         | 
| 86 67 | 
             
                alias_method :state, :state_with_scope
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                private
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                def create_scope?(name)
         | 
| 72 | 
            +
                  @state_machine.config.create_scopes && !@klass.respond_to?(name) && @klass.respond_to?(:aasm_create_scope)
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                def create_scope(name)
         | 
| 76 | 
            +
                  @klass.aasm_create_scope(@name, name) if create_scope?(name)
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def create_scopes(name)
         | 
| 80 | 
            +
                  if namespace?
         | 
| 81 | 
            +
                    # Create default scopes even when namespace? for backward compatibility
         | 
| 82 | 
            +
                    namepaced_name = "#{namespace}_#{name}"
         | 
| 83 | 
            +
                    create_scope(namepaced_name)
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
                  create_scope(name)
         | 
| 86 | 
            +
                end
         | 
| 87 87 | 
             
              end # Base
         | 
| 88 88 |  | 
| 89 89 | 
             
            end # AASM
         | 
| @@ -0,0 +1,94 @@ | |
| 1 | 
            +
            module AASM
         | 
| 2 | 
            +
              module Persistence
         | 
| 3 | 
            +
                module CoreDataQueryPersistence
         | 
| 4 | 
            +
                  # This method:
         | 
| 5 | 
            +
                  #
         | 
| 6 | 
            +
                  # * extends the model with ClassMethods
         | 
| 7 | 
            +
                  # * includes InstanceMethods
         | 
| 8 | 
            +
                  #
         | 
| 9 | 
            +
                  # Adds
         | 
| 10 | 
            +
                  #
         | 
| 11 | 
            +
                  #   after_initialize :aasm_ensure_initial_state
         | 
| 12 | 
            +
                  #
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def self.included(base)
         | 
| 15 | 
            +
                    base.send(:include, AASM::Persistence::Base)
         | 
| 16 | 
            +
                    base.send(:include, AASM::Persistence::CoreDataQueryPersistence::InstanceMethods)
         | 
| 17 | 
            +
                    base.extend AASM::Persistence::CoreDataQueryPersistence::ClassMethods
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    base.after_initialize :aasm_ensure_initial_state
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  module ClassMethods
         | 
| 23 | 
            +
                    def aasm_create_scope(state_machine_name, scope_name)
         | 
| 24 | 
            +
                      scope(scope_name.to_sym, lambda { where(aasm(state_machine_name).attribute_name.to_sym).eq(scope_name.to_s) })
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  module InstanceMethods
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                    # Writes <tt>state</tt> to the state column and persists it to the database
         | 
| 31 | 
            +
                    # using update_attribute (which bypasses validation)
         | 
| 32 | 
            +
                    #
         | 
| 33 | 
            +
                    #   foo = Foo.find(1)
         | 
| 34 | 
            +
                    #   foo.aasm.current_state # => :opened
         | 
| 35 | 
            +
                    #   foo.close!
         | 
| 36 | 
            +
                    #   foo.aasm.current_state # => :closed
         | 
| 37 | 
            +
                    #   Foo.find(1).aasm.current_state # => :closed
         | 
| 38 | 
            +
                    #
         | 
| 39 | 
            +
                    # NOTE: intended to be called from an event
         | 
| 40 | 
            +
                    def aasm_write_state(state, name=:default)
         | 
| 41 | 
            +
                      raise "Cowardly refusing to save the current CoreDataQuery context"
         | 
| 42 | 
            +
                      aasm_write_state_without_persistence(state, name)
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    # Writes <tt>state</tt> to the state column, but does not persist it to the database
         | 
| 46 | 
            +
                    #
         | 
| 47 | 
            +
                    #   foo = Foo.find(1)
         | 
| 48 | 
            +
                    #   foo.aasm.current_state # => :opened
         | 
| 49 | 
            +
                    #   foo.close
         | 
| 50 | 
            +
                    #   foo.aasm.current_state # => :closed
         | 
| 51 | 
            +
                    #   Foo.find(1).aasm.current_state # => :opened
         | 
| 52 | 
            +
                    #   foo.save
         | 
| 53 | 
            +
                    #   foo.aasm.current_state # => :closed
         | 
| 54 | 
            +
                    #   Foo.find(1).aasm.current_state # => :closed
         | 
| 55 | 
            +
                    #
         | 
| 56 | 
            +
                    # NOTE: intended to be called from an event
         | 
| 57 | 
            +
                    def aasm_write_state_without_persistence(state, name=:default)
         | 
| 58 | 
            +
                      write_attribute(self.class.aasm(name).attribute_name, state.to_s)
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  private
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                    # Ensures that if the aasm_state column is nil and the record is new
         | 
| 64 | 
            +
                    # that the initial state gets populated before validation on create
         | 
| 65 | 
            +
                    #
         | 
| 66 | 
            +
                    #   foo = Foo.new
         | 
| 67 | 
            +
                    #   foo.aasm_state # => nil
         | 
| 68 | 
            +
                    #   foo.valid?
         | 
| 69 | 
            +
                    #   foo.aasm_state # => "open" (where :open is the initial state)
         | 
| 70 | 
            +
                    #
         | 
| 71 | 
            +
                    #
         | 
| 72 | 
            +
                    #   foo = Foo.find(:first)
         | 
| 73 | 
            +
                    #   foo.aasm_state # => 1
         | 
| 74 | 
            +
                    #   foo.aasm_state = nil
         | 
| 75 | 
            +
                    #   foo.valid?
         | 
| 76 | 
            +
                    #   foo.aasm_state # => nil
         | 
| 77 | 
            +
                    #
         | 
| 78 | 
            +
                    def aasm_ensure_initial_state
         | 
| 79 | 
            +
                      AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
         | 
| 80 | 
            +
                        next if !send(self.class.aasm(state_machine_name).attribute_name) || send(self.class.aasm(state_machine_name).attribute_name).empty?
         | 
| 81 | 
            +
                        send("#{self.class.aasm(state_machine_name).attribute_name}=", aasm(state_machine_name).enter_initial_state.to_s)
         | 
| 82 | 
            +
                      end
         | 
| 83 | 
            +
                    end
         | 
| 84 | 
            +
                  end # InstanceMethods
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                  # module NamedScopeMethods
         | 
| 87 | 
            +
                  #   def aasm_state_with_named_scope name, options = {}
         | 
| 88 | 
            +
                  #     aasm_state_without_named_scope name, options
         | 
| 89 | 
            +
                  #     self.named_scope name, :conditions => { "#{table_name}.#{self.aasm.attribute_name}" => name.to_s} unless self.respond_to?(name)
         | 
| 90 | 
            +
                  #   end
         | 
| 91 | 
            +
                  # end
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
              end # Persistence
         | 
| 94 | 
            +
            end # AASM
         | 
| @@ -0,0 +1,92 @@ | |
| 1 | 
            +
            module AASM
         | 
| 2 | 
            +
              module Persistence
         | 
| 3 | 
            +
                module DynamoidPersistence
         | 
| 4 | 
            +
                  def self.included(base)
         | 
| 5 | 
            +
                    base.send(:include, AASM::Persistence::Base)
         | 
| 6 | 
            +
                    base.send(:include, AASM::Persistence::DynamoidPersistence::InstanceMethods)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                    base.after_initialize :aasm_ensure_initial_state
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    # Because Dynamoid only use define_method to add attribute assignment method in Class.
         | 
| 11 | 
            +
                    #
         | 
| 12 | 
            +
                    # In AASM::Base.initialize, it redefines and calls super in this method without superclass method.
         | 
| 13 | 
            +
                    # We override method_missing to solve this problem.
         | 
| 14 | 
            +
                    #
         | 
| 15 | 
            +
                    base.class_eval %Q(
         | 
| 16 | 
            +
                      def method_missing(method_name, *arguments, &block)
         | 
| 17 | 
            +
                        if (AASM::StateMachineStore.fetch(self.class, true).machine_names.map { |state_machine_name| self.class.aasm(state_machine_name).attribute_name.to_s + "=" }).include? method_name.to_s
         | 
| 18 | 
            +
                          attribute_name = method_name.to_s.gsub("=", '')
         | 
| 19 | 
            +
                          write_attribute(attribute_name.to_sym, *arguments)
         | 
| 20 | 
            +
                        else
         | 
| 21 | 
            +
                          super
         | 
| 22 | 
            +
                        end
         | 
| 23 | 
            +
                      end
         | 
| 24 | 
            +
                    )
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  module InstanceMethods
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    # Writes <tt>state</tt> to the state column and persists it to the database
         | 
| 30 | 
            +
                    # using update_attribute (which bypasses validation)
         | 
| 31 | 
            +
                    #
         | 
| 32 | 
            +
                    #   foo = Foo.find(1)
         | 
| 33 | 
            +
                    #   foo.aasm.current_state # => :opened
         | 
| 34 | 
            +
                    #   foo.close!
         | 
| 35 | 
            +
                    #   foo.aasm.current_state # => :closed
         | 
| 36 | 
            +
                    #   Foo.find(1).aasm.current_state # => :closed
         | 
| 37 | 
            +
                    #
         | 
| 38 | 
            +
                    # NOTE: intended to be called from an event
         | 
| 39 | 
            +
                    def aasm_write_state(state, name=:default)
         | 
| 40 | 
            +
                      old_value = read_attribute(self.class.aasm(name).attribute_name)
         | 
| 41 | 
            +
                      write_attribute(self.class.aasm(name).attribute_name, state.to_s)
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                      unless self.save(:validate => false)
         | 
| 44 | 
            +
                        write_attribute(self.class.aasm(name).attribute_name, old_value)
         | 
| 45 | 
            +
                        return false
         | 
| 46 | 
            +
                      end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      true
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    # Writes <tt>state</tt> to the state column, but does not persist it to the database
         | 
| 52 | 
            +
                    #
         | 
| 53 | 
            +
                    #   foo = Foo.find(1)
         | 
| 54 | 
            +
                    #   foo.aasm.current_state # => :opened
         | 
| 55 | 
            +
                    #   foo.close
         | 
| 56 | 
            +
                    #   foo.aasm.current_state # => :closed
         | 
| 57 | 
            +
                    #   Foo.find(1).aasm.current_state # => :opened
         | 
| 58 | 
            +
                    #   foo.save
         | 
| 59 | 
            +
                    #   foo.aasm.current_state # => :closed
         | 
| 60 | 
            +
                    #   Foo.find(1).aasm.current_state # => :closed
         | 
| 61 | 
            +
                    #
         | 
| 62 | 
            +
                    # NOTE: intended to be called from an event
         | 
| 63 | 
            +
                    def aasm_write_state_without_persistence(state, name=:default)
         | 
| 64 | 
            +
                      write_attribute(self.class.aasm(name).attribute_name, state.to_s)
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  private
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    # Ensures that if the aasm_state column is nil and the record is new
         | 
| 70 | 
            +
                    # that the initial state gets populated before validation on create
         | 
| 71 | 
            +
                    #
         | 
| 72 | 
            +
                    #   foo = Foo.new
         | 
| 73 | 
            +
                    #   foo.aasm_state # => nil
         | 
| 74 | 
            +
                    #   foo.valid?
         | 
| 75 | 
            +
                    #   foo.aasm_state # => "open" (where :open is the initial state)
         | 
| 76 | 
            +
                    #
         | 
| 77 | 
            +
                    #
         | 
| 78 | 
            +
                    #   foo = Foo.find(:first)
         | 
| 79 | 
            +
                    #   foo.aasm_state # => 1
         | 
| 80 | 
            +
                    #   foo.aasm_state = nil
         | 
| 81 | 
            +
                    #   foo.valid?
         | 
| 82 | 
            +
                    #   foo.aasm_state # => nil
         | 
| 83 | 
            +
                    #
         | 
| 84 | 
            +
                    def aasm_ensure_initial_state
         | 
| 85 | 
            +
                      AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
         | 
| 86 | 
            +
                        aasm(state_machine_name).enter_initial_state if !send(self.class.aasm(state_machine_name).attribute_name) || send(self.class.aasm(state_machine_name).attribute_name).empty?
         | 
| 87 | 
            +
                      end
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
                  end # InstanceMethods
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
              end # Persistence
         | 
| 92 | 
            +
            end # AASM
         | 
| @@ -1,5 +1,4 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 1 | 
            +
            require 'aasm/persistence/orm'
         | 
| 3 2 | 
             
            module AASM
         | 
| 4 3 | 
             
              module Persistence
         | 
| 5 4 | 
             
                module MongoidPersistence
         | 
| @@ -32,52 +31,58 @@ module AASM | |
| 32 31 | 
             
                  #
         | 
| 33 32 | 
             
                  def self.included(base)
         | 
| 34 33 | 
             
                    base.send(:include, AASM::Persistence::Base)
         | 
| 34 | 
            +
                    base.send(:include, AASM::Persistence::ORM)
         | 
| 35 35 | 
             
                    base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)
         | 
| 36 | 
            +
                    base.extend AASM::Persistence::MongoidPersistence::ClassMethods
         | 
| 36 37 |  | 
| 37 38 | 
             
                    base.after_initialize :aasm_ensure_initial_state
         | 
| 38 39 | 
             
                  end
         | 
| 39 40 |  | 
| 41 | 
            +
                  module ClassMethods
         | 
| 42 | 
            +
                    def aasm_create_scope(state_machine_name, scope_name)
         | 
| 43 | 
            +
                      scope_options = lambda {
         | 
| 44 | 
            +
                        send(
         | 
| 45 | 
            +
                          :where,
         | 
| 46 | 
            +
                          { aasm(state_machine_name).attribute_name.to_sym => scope_name.to_s }
         | 
| 47 | 
            +
                        )
         | 
| 48 | 
            +
                      }
         | 
| 49 | 
            +
                      send(:scope, scope_name, scope_options)
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
             | 
| 40 53 | 
             
                  module InstanceMethods
         | 
| 41 54 |  | 
| 42 | 
            -
                     | 
| 43 | 
            -
             | 
| 44 | 
            -
                     | 
| 45 | 
            -
             | 
| 46 | 
            -
                     | 
| 47 | 
            -
                    #   foo.close!
         | 
| 48 | 
            -
                    #   foo.aasm.current_state # => :closed
         | 
| 49 | 
            -
                    #   Foo.find(1).aasm.current_state # => :closed
         | 
| 50 | 
            -
                    #
         | 
| 51 | 
            -
                    # NOTE: intended to be called from an event
         | 
| 52 | 
            -
                    def aasm_write_state(state, name=:default)
         | 
| 53 | 
            -
                      old_value = read_attribute(self.class.aasm(name).attribute_name)
         | 
| 54 | 
            -
                      write_attribute(self.class.aasm(name).attribute_name, state.to_s)
         | 
| 55 | 
            +
                    private
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    def aasm_save
         | 
| 58 | 
            +
                      self.save
         | 
| 59 | 
            +
                    end
         | 
| 55 60 |  | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 61 | 
            +
                    def aasm_raise_invalid_record
         | 
| 62 | 
            +
                      raise Mongoid::Errors::Validations.new(self)
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    def aasm_supports_transactions?
         | 
| 66 | 
            +
                      false
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    def aasm_update_column(attribute_name, value)
         | 
| 70 | 
            +
                      if Mongoid::VERSION.to_f >= 4
         | 
| 71 | 
            +
                        set(Hash[attribute_name, value])
         | 
| 72 | 
            +
                      else
         | 
| 73 | 
            +
                        set(attribute_name, value)
         | 
| 59 74 | 
             
                      end
         | 
| 60 75 |  | 
| 61 76 | 
             
                      true
         | 
| 62 77 | 
             
                    end
         | 
| 63 78 |  | 
| 64 | 
            -
                     | 
| 65 | 
            -
             | 
| 66 | 
            -
                    #   foo = Foo.find(1)
         | 
| 67 | 
            -
                    #   foo.aasm.current_state # => :opened
         | 
| 68 | 
            -
                    #   foo.close
         | 
| 69 | 
            -
                    #   foo.aasm.current_state # => :closed
         | 
| 70 | 
            -
                    #   Foo.find(1).aasm.current_state # => :opened
         | 
| 71 | 
            -
                    #   foo.save
         | 
| 72 | 
            -
                    #   foo.aasm.current_state # => :closed
         | 
| 73 | 
            -
                    #   Foo.find(1).aasm.current_state # => :closed
         | 
| 74 | 
            -
                    #
         | 
| 75 | 
            -
                    # NOTE: intended to be called from an event
         | 
| 76 | 
            -
                    def aasm_write_state_without_persistence(state, name=:default)
         | 
| 77 | 
            -
                      write_attribute(self.class.aasm(name).attribute_name, state.to_s)
         | 
| 79 | 
            +
                    def aasm_read_attribute(name)
         | 
| 80 | 
            +
                      read_attribute(name)
         | 
| 78 81 | 
             
                    end
         | 
| 79 82 |  | 
| 80 | 
            -
             | 
| 83 | 
            +
                    def aasm_write_attribute(name, value)
         | 
| 84 | 
            +
                      write_attribute(name, value)
         | 
| 85 | 
            +
                    end
         | 
| 81 86 |  | 
| 82 87 | 
             
                    # Ensures that if the aasm_state column is nil and the record is new
         | 
| 83 88 | 
             
                    # that the initial state gets populated before validation on create
         | 
| @@ -95,8 +100,17 @@ module AASM | |
| 95 100 | 
             
                    #   foo.aasm_state # => nil
         | 
| 96 101 | 
             
                    #
         | 
| 97 102 | 
             
                    def aasm_ensure_initial_state
         | 
| 98 | 
            -
                      AASM:: | 
| 99 | 
            -
                         | 
| 103 | 
            +
                      AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
         | 
| 104 | 
            +
                        attribute_name = self.class.aasm(state_machine_name).attribute_name.to_s
         | 
| 105 | 
            +
                        # Do not load initial state when object attributes are not loaded,
         | 
| 106 | 
            +
                        # mongoid has_many relationship does not load child object attributes when
         | 
| 107 | 
            +
                        # only ids are loaded, for example parent.child_ids will not load child object attributes.
         | 
| 108 | 
            +
                        # This feature is introduced in mongoid > 4.
         | 
| 109 | 
            +
                        if attribute_names.include?(attribute_name) && !attributes[attribute_name] || attributes[attribute_name].empty?
         | 
| 110 | 
            +
                          # attribute_missing? is defined in mongoid > 4
         | 
| 111 | 
            +
                          return if Mongoid::VERSION.to_f >= 4 && attribute_missing?(attribute_name)
         | 
| 112 | 
            +
                          send("#{self.class.aasm(state_machine_name).attribute_name}=", aasm(state_machine_name).enter_initial_state.to_s)
         | 
| 113 | 
            +
                        end
         | 
| 100 114 | 
             
                      end
         | 
| 101 115 | 
             
                    end
         | 
| 102 116 | 
             
                  end # InstanceMethods
         |