1. 07 12月, 2015 1 次提交
    • G
      Introduce after_{create,update,delete}_commit callbacks · 5a300b2e
      Genadi Samokovarov 提交于
      Those are actually shortcuts for `after_commit`.
      
      Before:
      
          after_commit :add_to_index_later, on: :create
          after_commit :update_in_index_later, on: :update
          after_commit :remove_from_index_later, on: :destroy
      
      After:
      
          after_create_commit  :add_to_index_later
          after_update_commit  :update_in_index_later
          after_destroy_commit :remove_from_index_later
      5a300b2e
  2. 14 10月, 2015 1 次提交
    • Y
      applies new doc guidelines to Active Record. · 428d47ad
      Yves Senn 提交于
      The focus of this change is to make the API more accessible.
      References to method and classes should be linked to make it easy to
      navigate around.
      
      This patch makes exzessiv use of `rdoc-ref:` to provide more readable
      docs. This makes it possible to document `ActiveRecord::Base#save` even
      though the method is within a separate module
      `ActiveRecord::Persistence`. The goal here is to bring the API closer to
      the actual code that you would write.
      
      This commit only deals with Active Record. The other gems will be
      updated accordingly but in different commits. The pass through Active
      Record is not completely finished yet. A follow up commit will change
      the spots I haven't yet had the time to update.
      
      /cc @fxn
      428d47ad
  3. 23 9月, 2015 1 次提交
  4. 10 9月, 2015 1 次提交
  5. 20 7月, 2015 2 次提交
  6. 16 7月, 2015 1 次提交
    • G
      Revert "Revert "Reduce allocations when running AR callbacks."" · beb07fbf
      Guo Xiang Tan 提交于
      This reverts commit bdc1d329.
      
      Before:
      Calculating -------------------------------------
                              22.000  i/100ms
      -------------------------------------------------
                              229.700  (± 0.4%) i/s -      1.166k
      Total Allocated Object: 9939
      
      After:
      Calculating -------------------------------------
                              24.000  i/100ms
      -------------------------------------------------
                              246.443  (± 0.8%) i/s -      1.248k
      Total Allocated Object: 7939
      
      ```
      begin
        require 'bundler/inline'
      rescue LoadError => e
        $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
        raise e
      end
      
      gemfile(true) do
        source 'https://rubygems.org'
        # gem 'rails', github: 'rails/rails', ref: 'bdc1d329'
        gem 'rails', github: 'rails/rails', ref: 'd2876141'
        gem 'arel', github: 'rails/arel'
        gem 'sqlite3'
        gem 'benchmark-ips'
      end
      
      require 'active_record'
      require 'benchmark/ips'
      
      ActiveRecord::Base.establish_connection('sqlite3::memory:')
      
      ActiveRecord::Migration.verbose = false
      
      ActiveRecord::Schema.define do
        create_table :users, force: true do |t|
          t.string :name, :email
          t.boolean :admin
          t.timestamps null: false
        end
      end
      
      class User < ActiveRecord::Base
        default_scope { where(admin: true) }
      end
      
      admin = true
      
      1000.times do
        attributes = {
          name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          email: "foobar@email.com",
          admin: admin
        }
      
        User.create!(attributes)
      
        admin = !admin
      end
      
      GC.disable
      
      Benchmark.ips(5, 3) do |x|
        x.report { User.all.to_a }
      end
      
      key =
        if RUBY_VERSION < '2.2'
          :total_allocated_object
        else
          :total_allocated_objects
        end
      
      before = GC.stat[key]
      User.all.to_a
      after = GC.stat[key]
      puts "Total Allocated Object: #{after - before}"
      ```
      beb07fbf
  7. 12 5月, 2015 2 次提交
  8. 22 3月, 2015 1 次提交
  9. 10 3月, 2015 1 次提交
  10. 04 3月, 2015 2 次提交
  11. 03 3月, 2015 4 次提交
    • A
      Revert "mutate the transaction object to reflect state" · 07278519
      Aaron Patterson 提交于
      This reverts commit 393e65b4 and
      ec51c3fe
      
      We don't want the records to hold hard references to transactions
      because they point at records that have callbacks.
      07278519
    • A
      ask the txn for it's state, not a state object · ec51c3fe
      Aaron Patterson 提交于
      this way we don't have to mutate a state object, we can just change the
      state of the txn
      ec51c3fe
    • A
      Make private methods private · eeb1ab3a
      Arthur Neves 提交于
      eeb1ab3a
    • A
      Remove !has_transactional_callbacks? check · a45015d0
      Arthur Neves 提交于
      We only set the state on the record if that condition is `false` in the
      first place, so we dont need to call that again. Also that call is
      expensive, follow benchmark with before and after this change:
      
      ```
      Calculating -------------------------------------
                persisted?    15.272k i/100ms
      	  -------------------------------------------------
                persisted?    350.119k (± 4.6%) i/s -      1.756M
      ```
      
      ```
      Calculating -------------------------------------
                persisted?    25.988k i/100ms
      	  -------------------------------------------------
                persisted?      1.294M (± 5.3%) i/s -      6.445M
      ```
      
      (benchmark borrowed from 57d35b2b)
      a45015d0
  12. 02 3月, 2015 2 次提交
  13. 25 2月, 2015 2 次提交
  14. 02 2月, 2015 3 次提交
  15. 10 1月, 2015 1 次提交
  16. 06 1月, 2015 1 次提交
    • J
      Fix rollback of primarykey-less tables · f634c1fc
      Jonathan del Strother 提交于
      If you have a table without a primary key, and an `after_commit` callback on that table (ie `has_transactional_callbacks?` returns true), then trying to rollback a transaction involving that record would result in “ActiveModel::MissingAttributeError: can't write unknown attribute ``”
      f634c1fc
  17. 04 1月, 2015 1 次提交
  18. 03 1月, 2015 2 次提交
    • C
      Deprecate `false` as the way to halt AR callbacks · bb78af73
      claudiob 提交于
      Before this commit, returning `false` in an ActiveRecord `before_` callback
      such as `before_create` would halt the callback chain.
      
      After this commit, the behavior is deprecated: will still work until
      the next release of Rails but will also display a deprecation warning.
      
      The preferred way to halt a callback chain is to explicitly `throw(:abort)`.
      bb78af73
    • C
      Throw :abort halts default CallbackChains · 2386daab
      claudiob 提交于
      This commit changes arguments and default value of CallbackChain's :terminator
      option.
      
      After this commit, Chains of callbacks defined **without** an explicit
      `:terminator` option will be halted as soon as a `before_` callback throws
      `:abort`.
      
      Chains of callbacks defined **with** a `:terminator` option will maintain their
      existing behavior of halting as soon as a `before_` callback matches the
      terminator's expectation. For instance, ActiveModel's callbacks will still
      halt the chain when a `before_` callback returns `false`.
      2386daab
  19. 27 12月, 2014 1 次提交
  20. 20 12月, 2014 1 次提交
  21. 08 12月, 2014 1 次提交
    • C
      Make error message clearer that :on requires a symbol, not a string · ffce60e1
      Carol Nichols 提交于
      The validation added in 5a3dc809 will
      reject values for the `:on` option for after_commit and after_rollback
      callbacks that are string values like `"create"`.
      
      However, the error message says ":on conditions for after_commit and
      after_rollback callbacks have to be one of create,destroy,update". That
      looks like a string value *would* be valid.
      
      This commit changes the error message to say ":on conditions for
      after_commit and after_rollback callbacks have to be one of [:create,
      :destroy, :update]", making it clearer that symbols are required.
      ffce60e1
  22. 26 10月, 2014 1 次提交
  23. 15 10月, 2014 1 次提交
    • G
      Make the config actually copyable · 62f96c9e
      Godfrey Chan 提交于
      The intention here is to make the required config copy-able from the console/logs, so add a newline at the end of the message to make that easier. (Otherwise it would be `... raise_in_transactional_callbacks = true (called from...`.)
      62f96c9e
  24. 29 9月, 2014 1 次提交
    • P
      Reduce allocations when running AR callbacks. · 796cab45
      Pete Higgins 提交于
      Inspired by @tenderlove's work in
      c363fff2, this reduces the number of
      strings allocated when running callbacks for ActiveRecord instances. I
      measured that using this script:
      
      ```
      require 'objspace'
      require 'active_record'
      require 'allocation_tracer'
      
      ActiveRecord::Base.establish_connection adapter: "sqlite3",
                                              database: ":memory:"
      
      ActiveRecord::Base.connection.instance_eval do
        create_table(:articles) { |t| t.string :name }
      end
      
      class Article < ActiveRecord::Base; end
      a = Article.create name: "foo"
      a = Article.find a.id
      
      N = 10
      result = ObjectSpace::AllocationTracer.trace do
        N.times { Article.find a.id }
      end
      
      result.sort.each do |k,v|
        p k => v
      end
      puts "total: #{result.values.map(&:first).inject(:+)}"
      ```
      
      When I run this against master and this branch I get this output:
      
      ```
      pete@balloon:~/projects/rails/activerecord$ git checkout master
      M Gemfile
      Switched to branch 'master'
      pete@balloon:~/projects/rails/activerecord$ bundle exec ruby benchmark_allocation_with_callback_send.rb > allocations_before
      pete@balloon:~/projects/rails/activerecord$ git checkout remove-dynamic-send-on-built-in-callbacks
      M Gemfile
      Switched to branch 'remove-dynamic-send-on-built-in-callbacks'
      pete@balloon:~/projects/rails/activerecord$ bundle exec ruby benchmark_allocation_with_callback_send.rb > allocations_after
      pete@balloon:~/projects/rails/activerecord$ diff allocations_before allocations_after
      39d38
      <
      {["/home/pete/projects/rails/activesupport/lib/active_support/callbacks.rb",
      81]=>[40, 0, 0, 0, 0, 0]}
      42c41
      < total: 630
      ---
      > total: 590
      
      ```
      
      In addition to this, there are two micro-optimizations present:
      
      * Using `block.call if block` vs `yield if block_given?` when the block was being captured already.
      
      ```
      pete@balloon:~/projects$ cat benchmark_block_call_vs_yield.rb
      require 'benchmark/ips'
      
      def block_capture_with_yield &block
        yield if block_given?
      end
      
      def block_capture_with_call &block
        block.call if block
      end
      
      def no_block_capture
        yield if block_given?
      end
      
      Benchmark.ips do |b|
        b.report("block_capture_with_yield") { block_capture_with_yield }
        b.report("block_capture_with_call") { block_capture_with_call }
        b.report("no_block_capture") { no_block_capture }
      end
      pete@balloon:~/projects$ ruby benchmark_block_call_vs_yield.rb
      Calculating -------------------------------------
      block_capture_with_yield
                              124979 i/100ms
      block_capture_with_call
                              138340 i/100ms
          no_block_capture    136827 i/100ms
      -------------------------------------------------
      block_capture_with_yield
                            5703108.9 (±2.4%) i/s -   28495212 in   4.999368s
      block_capture_with_call
                            6840730.5 (±3.6%) i/s -   34169980 in   5.002649s
          no_block_capture  5821141.4 (±2.8%) i/s -   29144151 in   5.010580s
      ```
      
      * Defining and calling methods instead of using send.
      
      ```
      pete@balloon:~/projects$ cat benchmark_method_call_vs_send.rb
      require 'benchmark/ips'
      
      class Foo
        def tacos
          nil
        end
      end
      
      my_foo = Foo.new
      
      Benchmark.ips do |b|
        b.report('send') { my_foo.send('tacos') }
        b.report('call') { my_foo.tacos }
      end
      pete@balloon:~/projects$ ruby benchmark_method_call_vs_send.rb
      Calculating -------------------------------------
                      send     97736 i/100ms
                      call    151142 i/100ms
      -------------------------------------------------
                      send  2683730.3 (±2.8%) i/s -   13487568 in   5.029763s
                      call  8005963.9 (±2.7%) i/s -   40052630 in   5.006604s
      ```
      
      The result of this is making typical ActiveRecord operations slightly faster:
      
      https://gist.github.com/phiggins/e46e51dcc7edb45b5f98
      796cab45
  25. 29 8月, 2014 1 次提交
    • G
      Avoid using heredoc for user warnings · 8c52480b
      Godfrey Chan 提交于
      Using heredoc would enforce line wrapping to whatever column width we decided to
      use in the code, making it difficult for the users to read on some consoles.
      
      This does make the source code read slightly worse and a bit more error-prone,
      but this seems like a fair price to pay since the primary purpose for these
      messages are for the users to read and the code will not stick around for too
      long.
      8c52480b
  26. 28 8月, 2014 1 次提交
  27. 19 8月, 2014 2 次提交
    • A
      Fix after_commit warning message · 98c3f55a
      Arthur Neves 提交于
      98c3f55a
    • A
      Add option to stop swallowing errors on callbacks. · b11b1e86
      Arthur Neves 提交于
      Currently, Active Record will rescue any errors raised within
      after_rollback/after_create callbacks and print them to the
      logs. Next versions of rails will not rescue those errors anymore,
      and just bubble them up, as the other callbacks.
      
      This adds a opt-in flag to enable that behaviour, of not rescuing
      the errors.
          Example:
            # For not swallow errors in after_commit/after_rollback
            config.active_record.errors_in_transactional_callbacks = true
      
      [fixes #13460]
      b11b1e86
  28. 08 6月, 2014 1 次提交
    • S
      Move conditionals about freezing closer to the definition of `freeze` · 105e0304
      Sean Griffin 提交于
      Reduces the number of places that care about the internals of how we
      store and type cast attributes. We do not need to go through the
      dup/freeze dance, as you couldn't have saved a frozen new record anyway,
      and that is the only time we would end up modifying the frozen hash.
      105e0304