aasm 4.5.1 → 4.5.2
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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/aasm/core/transition.rb +1 -1
- data/lib/aasm/persistence/active_record_persistence.rb +24 -9
- data/lib/aasm/persistence/base.rb +52 -25
- data/lib/aasm/version.rb +1 -1
- data/spec/models/guardian.rb +10 -0
- data/spec/unit/guard_spec.rb +12 -0
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 497994639dac4183fdf996cafad384f308784855
         | 
| 4 | 
            +
              data.tar.gz: 731e388e865ffb526e4cbb3c20443659aab8605a
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: b3572795abc66917c392e8736afc6d8ea882b12f0fdfcb15cd8046ae0f1977e8dd01b2eeab5d2fcb7e659295c3f45b6aa438aa008c61c8707370be7b27b40e31
         | 
| 7 | 
            +
              data.tar.gz: 42a4dc5b04c7a13e2a15e745a42b960a80cb4a90f4f62e1eb51c09b4493565314c85ae4aeeb1dd985fc85094706b440fc14ec11dbb7e7275c641e64309b7106d
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,9 @@ | |
| 1 1 | 
             
            # CHANGELOG
         | 
| 2 2 |  | 
| 3 | 
            +
            ## 4.5.2
         | 
| 4 | 
            +
             | 
| 5 | 
            +
             * fix arity difference between Procs and lambdas (see [issue #293](https://github.com/aasm/aasm/issues/293) for details)
         | 
| 6 | 
            +
             | 
| 3 7 | 
             
            ## 4.5.1
         | 
| 4 8 |  | 
| 5 9 | 
             
             * make sure to use override configuration options if state machine is defined more than once (see [issue #287](https://github.com/aasm/aasm/issues/287) for details)
         | 
    
        data/lib/aasm/core/transition.rb
    CHANGED
    
    | @@ -55,7 +55,7 @@ module AASM::Core | |
| 55 55 | 
             
                    arity = record.send(:method, code.to_sym).arity
         | 
| 56 56 | 
             
                    arity == 0 ? record.send(code) : record.send(code, *args)
         | 
| 57 57 | 
             
                  when Proc
         | 
| 58 | 
            -
                    code. | 
| 58 | 
            +
                    code.parameters.size == 0 ? record.instance_exec(&code) : record.instance_exec(*args, &code)
         | 
| 59 59 | 
             
                  when Array
         | 
| 60 60 | 
             
                    if options[:guard]
         | 
| 61 61 | 
             
                      # invoke guard callbacks
         | 
| @@ -57,16 +57,12 @@ module AASM | |
| 57 57 |  | 
| 58 58 | 
             
                      success = if aasm_skipping_validations(name)
         | 
| 59 59 | 
             
                        value = aasm_raw_attribute_value(state, name)
         | 
| 60 | 
            -
                         | 
| 60 | 
            +
                        aasm_update_column(name, value)
         | 
| 61 61 | 
             
                      else
         | 
| 62 62 | 
             
                        self.save
         | 
| 63 63 | 
             
                      end
         | 
| 64 | 
            -
                      unless success
         | 
| 65 | 
            -
                        write_attribute(self.class.aasm(name).attribute_name, old_value)
         | 
| 66 | 
            -
                        return false
         | 
| 67 | 
            -
                      end
         | 
| 68 64 |  | 
| 69 | 
            -
                      true
         | 
| 65 | 
            +
                      success ? true : aasm_rollback(name, old_value)
         | 
| 70 66 | 
             
                    end
         | 
| 71 67 |  | 
| 72 68 | 
             
                    # Writes <tt>state</tt> to the state column, but does not persist it to the database
         | 
| @@ -86,6 +82,16 @@ module AASM | |
| 86 82 | 
             
                    end
         | 
| 87 83 |  | 
| 88 84 | 
             
                  private
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    def aasm_update_column(name, value)
         | 
| 87 | 
            +
                      self.class.where(self.class.primary_key => self.id).update_all(self.class.aasm(name).attribute_name => value) == 1
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                    def aasm_rollback(name, old_value)
         | 
| 91 | 
            +
                      write_attribute(self.class.aasm(name).attribute_name, old_value)
         | 
| 92 | 
            +
                      false
         | 
| 93 | 
            +
                    end
         | 
| 94 | 
            +
             | 
| 89 95 | 
             
                    def aasm_enum(name=:default)
         | 
| 90 96 | 
             
                      case AASM::StateMachine[self.class][name].config.enum
         | 
| 91 97 | 
             
                        when false then nil
         | 
| @@ -120,7 +126,7 @@ module AASM | |
| 120 126 | 
             
                    end
         | 
| 121 127 |  | 
| 122 128 | 
             
                    # Ensures that if the aasm_state column is nil and the record is new
         | 
| 123 | 
            -
                    #  | 
| 129 | 
            +
                    # then the initial state gets populated before validation on create
         | 
| 124 130 | 
             
                    #
         | 
| 125 131 | 
             
                    #   foo = Foo.new
         | 
| 126 132 | 
             
                    #   foo.aasm_state # => nil
         | 
| @@ -138,12 +144,17 @@ module AASM | |
| 138 144 | 
             
                      AASM::StateMachine[self.class].keys.each do |state_machine_name|
         | 
| 139 145 | 
             
                        # checking via respond_to? does not work in Rails <= 3
         | 
| 140 146 | 
             
                        # 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  | 
| 147 | 
            +
                        if aasm_column_is_blank?(state_machine_name)
         | 
| 142 148 | 
             
                          aasm(state_machine_name).enter_initial_state
         | 
| 143 149 | 
             
                        end
         | 
| 144 150 | 
             
                      end
         | 
| 145 151 | 
             
                    end
         | 
| 146 152 |  | 
| 153 | 
            +
                    def aasm_column_is_blank?(state_machine_name)
         | 
| 154 | 
            +
                      attribute_name = self.class.aasm(state_machine_name).attribute_name
         | 
| 155 | 
            +
                      attribute_names.include?(attribute_name.to_s) && send(attribute_name).blank?
         | 
| 156 | 
            +
                    end
         | 
| 157 | 
            +
             | 
| 147 158 | 
             
                    def aasm_fire_event(state_machine_name, name, options, *args, &block)
         | 
| 148 159 | 
             
                      success = options[:persist] ? self.class.transaction(:requires_new => requires_new?(state_machine_name)) { super } : super
         | 
| 149 160 |  | 
| @@ -162,12 +173,16 @@ module AASM | |
| 162 173 | 
             
                    def aasm_validate_states
         | 
| 163 174 | 
             
                      AASM::StateMachine[self.class].keys.each do |state_machine_name|
         | 
| 164 175 | 
             
                        unless aasm_skipping_validations(state_machine_name)
         | 
| 165 | 
            -
                          if  | 
| 176 | 
            +
                          if aasm_invalid_state?(state_machine_name)
         | 
| 166 177 | 
             
                            self.errors.add(AASM::StateMachine[self.class][state_machine_name].config.column , "is invalid")
         | 
| 167 178 | 
             
                          end
         | 
| 168 179 | 
             
                        end
         | 
| 169 180 | 
             
                      end
         | 
| 170 181 | 
             
                    end
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                    def aasm_invalid_state?(state_machine_name)
         | 
| 184 | 
            +
                      aasm(state_machine_name).current_state && !aasm(state_machine_name).states.include?(aasm(state_machine_name).current_state)
         | 
| 185 | 
            +
                    end
         | 
| 171 186 | 
             
                  end # InstanceMethods
         | 
| 172 187 |  | 
| 173 188 | 
             
                end
         | 
| @@ -55,35 +55,62 @@ module AASM | |
| 55 55 | 
             
                # make sure to create a (named) scope for each state
         | 
| 56 56 | 
             
                def state_with_scope(name, *args)
         | 
| 57 57 | 
             
                  state_without_scope(name, *args)
         | 
| 58 | 
            -
                  if  | 
| 58 | 
            +
                  create_scope(name) if create_scope?(name)
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
                alias_method :state_without_scope, :state
         | 
| 61 | 
            +
                alias_method :state, :state_with_scope
         | 
| 59 62 |  | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 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
         | 
| 63 | 
            +
                private
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                def create_scope?(name)
         | 
| 66 | 
            +
                  @state_machine.config.create_scopes && !@klass.respond_to?(name)
         | 
| 67 | 
            +
                end
         | 
| 82 68 |  | 
| 69 | 
            +
                def create_scope(name)
         | 
| 70 | 
            +
                  if ancestors_include?("ActiveRecord::Base")
         | 
| 71 | 
            +
                    create_for_active_record(name)
         | 
| 72 | 
            +
                  elsif ancestors_include?("Mongoid::Document")
         | 
| 73 | 
            +
                    create_for_mongoid(name)
         | 
| 74 | 
            +
                  elsif ancestors_include?("MongoMapper::Document")
         | 
| 75 | 
            +
                    create_for_mongomapper(name)
         | 
| 83 76 | 
             
                  end
         | 
| 84 77 | 
             
                end
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                 | 
| 78 | 
            +
             | 
| 79 | 
            +
                def ancestors_include?(class_name)
         | 
| 80 | 
            +
                  @klass.ancestors.map { |klass| klass.to_s }.include?(class_name)
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                def create_for_active_record(name)
         | 
| 84 | 
            +
                  conditions = {
         | 
| 85 | 
            +
                    "#{@klass.table_name}.#{@klass.aasm(@name).attribute_name}" => name.to_s
         | 
| 86 | 
            +
                  }
         | 
| 87 | 
            +
                  if ActiveRecord::VERSION::MAJOR >= 3
         | 
| 88 | 
            +
                    @klass.class_eval do
         | 
| 89 | 
            +
                      scope name, lambda { where(conditions) }
         | 
| 90 | 
            +
                    end
         | 
| 91 | 
            +
                  else
         | 
| 92 | 
            +
                    @klass.class_eval do
         | 
| 93 | 
            +
                      named_scope name, :conditions => conditions
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                def create_for_mongoid(name)
         | 
| 99 | 
            +
                  klass = @klass
         | 
| 100 | 
            +
                  state_machine_name = @name
         | 
| 101 | 
            +
                  scope_options = lambda {
         | 
| 102 | 
            +
                    klass.send(
         | 
| 103 | 
            +
                      :where,
         | 
| 104 | 
            +
                      { klass.aasm(state_machine_name).attribute_name.to_sym => name.to_s }
         | 
| 105 | 
            +
                    )
         | 
| 106 | 
            +
                  }
         | 
| 107 | 
            +
                  @klass.send(:scope, name, scope_options)
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                def create_for_mongomapper(name)
         | 
| 111 | 
            +
                  conditions = { @klass.aasm(@name).attribute_name.to_sym => name.to_s }
         | 
| 112 | 
            +
                  @klass.scope(name, lambda { @klass.where(conditions) })
         | 
| 113 | 
            +
                end
         | 
| 87 114 | 
             
              end # Base
         | 
| 88 115 |  | 
| 89 116 | 
             
            end # AASM
         | 
    
        data/lib/aasm/version.rb
    CHANGED
    
    
    
        data/spec/models/guardian.rb
    CHANGED
    
    | @@ -1,6 +1,9 @@ | |
| 1 1 | 
             
            class Guardian
         | 
| 2 2 | 
             
              include AASM
         | 
| 3 3 |  | 
| 4 | 
            +
              def inner_guard(options={})
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
             | 
| 4 7 | 
             
              aasm do
         | 
| 5 8 | 
             
                state :alpha, :initial => true
         | 
| 6 9 | 
             
                state :beta
         | 
| @@ -12,6 +15,13 @@ class Guardian | |
| 12 15 | 
             
                  transitions :from => :alpha, :to => :beta, :guard => :fail
         | 
| 13 16 | 
             
                end
         | 
| 14 17 |  | 
| 18 | 
            +
                event :use_proc_guard_with_params do
         | 
| 19 | 
            +
                  transitions :from => :alpha, :to => :beta, :guard => Proc.new { |options={}| inner_guard(options) }
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
                event :use_lambda_guard_with_params do
         | 
| 22 | 
            +
                  transitions :from => :alpha, :to => :beta, :guard => lambda { |options={}| inner_guard(options) }
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 15 25 | 
             
                event :use_guards_that_succeed do
         | 
| 16 26 | 
             
                  transitions :from => :alpha, :to => :beta, :guards => [:succeed, :another_succeed]
         | 
| 17 27 | 
             
                end
         | 
    
        data/spec/unit/guard_spec.rb
    CHANGED
    
    | @@ -27,6 +27,18 @@ describe "per-transition guards" do | |
| 27 27 | 
             
                expect { guardian.use_guards_where_the_second_fails! }.to raise_error(AASM::InvalidTransition)
         | 
| 28 28 | 
             
                expect(guardian).to be_alpha
         | 
| 29 29 | 
             
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              describe "with params" do
         | 
| 32 | 
            +
                it "using a Proc" do
         | 
| 33 | 
            +
                  expect(guardian).to receive(:inner_guard).with({:flag => true}).and_return(true)
         | 
| 34 | 
            +
                  guardian.use_proc_guard_with_params(:flag => true)
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                it "using a lambda" do
         | 
| 38 | 
            +
                  expect(guardian).to receive(:inner_guard).with({:flag => true}).and_return(true)
         | 
| 39 | 
            +
                  guardian.use_lambda_guard_with_params(:flag => true)
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 30 42 | 
             
            end
         | 
| 31 43 |  | 
| 32 44 | 
             
            describe "event guards" do
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: aasm
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 4.5. | 
| 4 | 
            +
              version: 4.5.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Scott Barron
         | 
| @@ -10,7 +10,7 @@ authors: | |
| 10 10 | 
             
            autorequire: 
         | 
| 11 11 | 
             
            bindir: bin
         | 
| 12 12 | 
             
            cert_chain: []
         | 
| 13 | 
            -
            date:  | 
| 13 | 
            +
            date: 2016-01-06 00:00:00.000000000 Z
         | 
| 14 14 | 
             
            dependencies:
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 16 | 
             
              name: rake
         |