1. 25 10月, 2014 1 次提交
    • D
      Use type column first in multi-column indexes · 9cdd0a1f
      Derek Prior 提交于
      `add_reference` can very helpfully add a multi-column index when you use
      it to add a polymorphic reference. However, the first column in the
      index is the `id` column, which is less than ideal.
      
      The [PostgreSQL docs][1] say:
      > A multicolumn B-tree index can be used with query conditions that
      > involve any subset of the index's columns, but the index is most
      > efficient when there are constraints on the leading (leftmost)
      > columns.
      
      The [MySQL docs][2] say:
      > MySQL can use multiple-column indexes for queries that test all the
      > columns in the index, or queries that test just the first column, the
      > first two columns, the first three columns, and so on. If you specify
      > the columns in the right order in the index definition, a single
      > composite index can speed up several kinds of queries on the same
      > table.
      
      In a polymorphic relationship, the type column is much more likely to be
      useful as the first column in an index than the id column. That is, I'm
      more likely to query on type without an id than I am to query on id
      without a type.
      
      [1]: http://www.postgresql.org/docs/9.3/static/indexes-multicolumn.html
      [2]: http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html
      9cdd0a1f
  2. 21 10月, 2014 1 次提交
    • C
      Remove duplicate 'select' database statement · ec981aa1
      claudiob 提交于
      The `select` method has the same definition in almost all database
      adapters, so it can be moved from the database-specific adapters
      (PostgreSQl, MySQL, SQLite) to the abstract `database_statement`:
      
      ```ruby
      def select(sql, name = nil, binds = [])
        exec_query(sql, name, binds)
      end
      ```
      
      ---
      
      More details about this commit: the only two DB-specific adapters
      that have a different definition of `select` are MySQLAdapter and
      MySQL2Adapter.
      
      In MySQLAdapter, `select` invokes `exec_query(sql, name, binds)`, so
      calling `super` achieves the same goal with less repetition.
      
      In MySQL2Adapter, `select` invokes `exec_query(sql, name)`, that is,
      it does not pass the `binds` parameter like other methods do. However,
      [MySQL2Adapter's `exec_query`](https://github.com/rails/rails/blob/74a527cc63ef56f3d0a42cf638299958dc7cb08c/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L228L231)
      works exactly the same whether this parameters is passed or not, so the output
      does not change:
      
      ```ruby
      def exec_query(sql, name = 'SQL', binds = [])
        result = execute(sql, name)
        ActiveRecord::Result.new(result.fields, result.to_a)
      end
      ```
      ec981aa1
  3. 20 10月, 2014 3 次提交
  4. 17 10月, 2014 1 次提交
    • S
      Add a deprecation warning for abiguous boolean values · e01a46f1
      Sean Griffin 提交于
      In Rails 5.0, we'd like to change the behavior of boolean columns in
      Rails to be closer to Ruby's semantics. Currently we have a small set
      of values which are "truthy", and all others are "falsy". In Rails 5.0,
      we will reverse this to have a small number of values which are "falsy",
      and all others will become "truthy".
      
      In the interim, all values which are ambiguous must emit a deprecation
      warning.
      e01a46f1
  5. 16 10月, 2014 7 次提交
  6. 15 10月, 2014 5 次提交
  7. 14 10月, 2014 4 次提交
  8. 13 10月, 2014 1 次提交
    • A
      Autosave callbacks shouldn't be `after_save` · 719d52db
      Agis- 提交于
      068f092c registered autosave callbacks
      as `after_save` callbacks. This caused the regression described in #17209.
      
      Autosave callbacks should be registered as `after_update` and
      `after_create` callbacks, just like before.
      
      This is a partial revert of 068f092c.
      
      Fixes #17209.
      719d52db
  9. 07 10月, 2014 1 次提交
  10. 06 10月, 2014 1 次提交
  11. 04 10月, 2014 1 次提交
  12. 01 10月, 2014 1 次提交
  13. 29 9月, 2014 3 次提交
    • E
      Use Hash#each_key instead of Hash#keys.each · e2b49b20
      Erik Michaels-Ober 提交于
      Hash#keys.each allocates an array of keys; Hash#each_key iterates through the
      keys without allocating a new array. This is the reason why Hash#each_key
      exists.
      e2b49b20
    • B
      Remove defunct ivars · 588c321e
      Ben Woosley 提交于
      @column_names_with_alias, @dynamic_methods_hash, @time_zone_column_names, and @cached_time_zone
      588c321e
    • 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
  14. 27 9月, 2014 2 次提交
    • A
      some object allocation reduction for new AR objects · c363fff2
      Aaron Patterson 提交于
      Benchmark:
      
      ```ruby
      require 'objspace'
      require 'active_record'
      
      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
      ObjectSpace::AllocationTracer.trace do
        N.times { Article.find a.id }
      end
      ObjectSpace::AllocationTracer.allocated_count_table
      table.sort_by { |_,x| x }.each do |k,v|
        p k => (v / N)
      end
      ```
      c363fff2
    • R
      Preparing for 4.2.0.beta2 release · 4581d044
      Rafael Mendonça França 提交于
      4581d044
  15. 23 9月, 2014 4 次提交
  16. 20 9月, 2014 3 次提交
  17. 19 9月, 2014 1 次提交