1. 10 6月, 2020 1 次提交
  2. 09 6月, 2020 5 次提交
  3. 08 6月, 2020 2 次提交
  4. 07 6月, 2020 8 次提交
    • R
      Fixup CHANGELOGs [ci skip] · cfb7c16a
      Ryuta Kamizono 提交于
      cfb7c16a
    • R
      Merge pull request #39560 from kamipo/casecmp · 40877d82
      Ryuta Kamizono 提交于
      Case insensitive mutation tracking
      40877d82
    • R
      Merge pull request #39558 from kamipo/support_relation_and_or · f4baf0f7
      Ryuta Kamizono 提交于
      Support `relation.and` for intersection as Set theory
      f4baf0f7
    • R
      Case insensitive mutation tracking · dbdd68b6
      Ryuta Kamizono 提交于
      It is cheaper than mutating casted value directly.
      
      See https://github.com/rails/rails/pull/38867#issuecomment-639238234 for
      more details.
      dbdd68b6
    • R
      Support `relation.and` for intersection as Set theory · 7219eb2c
      Ryuta Kamizono 提交于
      As described at #39328, `relation.merge` behaves inspired as Hash-like
      merge for where clause. In other words, currently there is no official
      way to intersect the result by both relation conditions (i.e. there is
      no official way to maintain both relation conditions).
      
      To resolve that issue, I'd like to support a way to intersect relations
      as `relation.and`.
      
      ```ruby
      david_and_mary = Author.where(id: [david, mary])
      mary_and_bob   = Author.where(id: [mary, bob]) # => [bob]
      
      david_and_mary.merge(mary_and_bob) # => [mary, bob]
      
      david_and_mary.and(mary_and_bob) # => [mary]
      david_and_mary.or(mary_and_bob)  # => [david, mary, bob]
      ```
      
      Fixes #39232.
      7219eb2c
    • R
      Make predicate builder about 2x faster · a1d236e9
      Ryuta Kamizono 提交于
      Extra predicate handler for just one line preprocess is too expensive.
      
      ```ruby
      ActiveRecord::Schema.define do
        create_table :users, force: true do |t|
        end
      end
      
      class User < ActiveRecord::Base
      end
      
      predicate_builder = User.predicate_builder
      
      attr = User.arel_attribute(:id)
      user = User.create!
      user_id = user.id
      
      Benchmark.ips do |x|
        x.report("build:user") { predicate_builder.build(attr, user) }
        x.report("build:user_id") { predicate_builder.build(attr, user_id) }
      end
      ```
      
      Before:
      
      ```
      Warming up --------------------------------------
                build:user    11.626k i/100ms
             build:user_id    23.314k i/100ms
      Calculating -------------------------------------
                build:user    114.151k (± 2.0%) i/s -    581.300k in   5.094468s
             build:user_id    226.420k (± 2.3%) i/s -      1.142M in   5.048205s
      ```
      
      After:
      
      ```
      Warming up --------------------------------------
                build:user    21.484k i/100ms
             build:user_id    24.307k i/100ms
      Calculating -------------------------------------
                build:user    210.207k (± 1.8%) i/s -      1.053M in   5.009623s
             build:user_id    238.276k (± 2.1%) i/s -      1.215M in   5.102951s
      ```
      a1d236e9
    • R
      Merge pull request #39328 from kamipo/deprecate_inconsistent_merging_behavior · 159cc342
      Ryuta Kamizono 提交于
      Deprecate inconsistent behavior that merging conditions on the same column
      159cc342
    • R
      Deprecate inconsistent behavior that merging conditions on the same column · 930bfb93
      Ryuta Kamizono 提交于
      Related to #39250 and #39236.
      
      The purpose of the change here is to unify inconsistent behavior on the
      merging.
      
      For now, mergee side condition is replaced by merger side condition only
      if both arel nodes are Equality or In clauses.
      
      In other words, if mergee side condition is not Equality or In clauses
      (e.g. `between`, `or`, `gt`, `lt`, etc), those conditions will be kept
      even on the same column.
      
      This behavior is harder to predict unless people are familiar with the
      merging behavior.
      
      Originally I suppose this behavior is just an implementation issue
      rather than an intended one, since `unscope` and `rewhere`, which were
      introduced later than `merge`, works more consistently.
      
      Since most of the conditions are usually Equality and In clauses, I
      don't suppose most people have encountered this merging issue, but I'd
      like to deprecate the inconsistent behavior and will completely unify
      that to improve a future UX.
      
      ```ruby
      # Rails 6.1 (IN clause is replaced by merger side equality condition)
      Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
      
      # Rails 6.1 (both conflict conditions exists, deprecated)
      Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []
      
      # Rails 6.1 with rewhere to migrate to Rails 6.2's behavior
      Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob]
      
      # Rails 6.2 (same behavior with IN clause, mergee side condition is consistently replaced)
      Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
      Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
      ```
      930bfb93
  5. 06 6月, 2020 2 次提交
    • E
      Merge pull request #39534 from eileencodes/route-with-params-object · 95af87f0
      Eileen M. Uchitelle 提交于
      Convert route params array into object
      95af87f0
    • E
      Convert route params array into object · 437ab203
      eileencodes 提交于
      This PR converts the route params array into an object and moves the
      error generation code into its own object as well. This is a refactoring
      of internal code to make it easier to change and simplier for internals
      to interface with. We have two new objects:
      
      1) `RouteWithParams`
      
      Previously `#generate` returned an array of parameterized parts for a
      route. We have now turned this into an object with a `path` and a
      `params methods` to be able to access the parts we need.
      
      2) `MissingRoute`
      
      `#generate` was also responsible for constructing the message for the
      error. We've moved this code into the new `MissingRoute` object so it
      does that work instead.
      
      This change makes these methods reusable throughout the code and easier
      for future refactoring we plan to do.
      Co-authored-by: NAaron Patterson <aaron.patterson@gmail.com>
      437ab203
  6. 05 6月, 2020 13 次提交
    • K
      Merge pull request #39541 from jonathanhefner/silence-rake-task-backtraces · 4654f4aa
      Kasper Timm Hansen 提交于
      Silence Rake task backtraces
      4654f4aa
    • J
      Silence Rake task backtraces · 7ba531be
      Jonathan Hefner 提交于
      Silence Rake task backtraces, similar to Rails::BacktraceCleaner.
      Application lines are preserved, but all other lines are hidden.
      
      This also affects unrecognized tasks, causing the backtrace to be hidden
      entirely.  Closes #39524.
      Co-authored-by: NPetrik <petrik@deheus.net>
      7ba531be
    • R
      Auto-correct for `delete_prefix`/`delete_suffix` · c07dff72
      Ryuta Kamizono 提交于
      Follow up to #39409.
      c07dff72
    • R
      Don't give up statement cache just because of there is one `composed_of` · c2dc793e
      Ryuta Kamizono 提交于
      It is too pessimistic, we can check the attribute whether aggregated or
      not by `reflect_on_aggregation`.
      c2dc793e
    • R
      Use statement cache for `find_by(author: david)` · dbda5feb
      Ryuta Kamizono 提交于
      ```ruby
      ActiveRecord::Schema.define do
        create_table :posts, force: true do |t|
        end
      
        create_table :comments, force: true do |t|
          t.belongs_to :post
        end
      end
      
      class Post < ActiveRecord::Base
        has_many :comments
      end
      
      class Comment < ActiveRecord::Base
        belongs_to :post
      end
      
      post = Post.create!
      
      Benchmark.ips do |x|
        x.report("find_by post") { Comment.find_by(post: post) }
      end
      ```
      
      Before:
      
      ```
      Warming up --------------------------------------
              find_by post   395.000  i/100ms
      Calculating -------------------------------------
              find_by post      4.026k (± 3.1%) i/s -     20.145k in   5.008059s
      ```
      
      After:
      
      ```
      Warming up --------------------------------------
              find_by post     1.183k i/100ms
      Calculating -------------------------------------
              find_by post     11.859k (± 2.5%) i/s -     60.333k in   5.090685s
      ```
      dbda5feb
    • R
      Revert "Lock benchmark-ips version "< 2.8"" · 60bfed90
      Ryuta Kamizono 提交于
      This reverts commit c1b8833e.
      
      Revert "Lock benchmark-ips version < 2.8"
      
      This reverts commit 62bfa50f.
      
      LoadError is fixed in benchmark-ips 2.8.2.
      
      https://github.com/evanphx/benchmark-ips/pull/101
      60bfed90
    • R
      PERF: 15% faster attribute access · 27a1ca2b
      Ryuta Kamizono 提交于
      Delegating to just one line method is to not be worth it.
      Avoiding the delegation makes `read_attribute` about 15% faster.
      
      ```ruby
      ActiveRecord::Schema.define do
        create_table :users, force: true do |t|
          t.string :name
        end
      end
      
      class User < ActiveRecord::Base
        def fast_read_attribute(attr_name, &block)
          name = attr_name.to_s
          name = self.class.attribute_aliases[name] || name
      
          name = @primary_key if name == "id" && @primary_key
          @attributes.fetch_value(name, &block)
        end
      end
      
      user = User.create!(name: "user name")
      
      Benchmark.ips do |x|
        x.report("read_attribute('id')") { user.read_attribute('id') }
        x.report("read_attribute('name')") { user.read_attribute('name') }
        x.report("fast_read_attribute('id')") { user.fast_read_attribute('id') }
        x.report("fast_read_attribute('name')") { user.fast_read_attribute('name') }
      end
      ```
      
      ```
      Warming up --------------------------------------
      read_attribute('id')   165.744k i/100ms
      read_attribute('name')
                             162.229k i/100ms
      fast_read_attribute('id')
                             192.543k i/100ms
      fast_read_attribute('name')
                             191.209k i/100ms
      Calculating -------------------------------------
      read_attribute('id')      1.648M (± 1.7%) i/s -      8.287M in   5.030170s
      read_attribute('name')
                                1.636M (± 3.9%) i/s -      8.274M in   5.065356s
      fast_read_attribute('id')
                                1.918M (± 1.8%) i/s -      9.627M in   5.021271s
      fast_read_attribute('name')
                                1.928M (± 0.9%) i/s -      9.752M in   5.058820s
      ```
      27a1ca2b
    • R
      Merge pull request #39537 from vipulnsward/self-join · b0231a7a
      Ryuta Kamizono 提交于
      Expand on specs for foreign keys with to_table and add make doc changes
      b0231a7a
    • E
      Merge pull request #39536 from eileencodes/remove-assumption-that-primary-exists · e95edb3d
      Eileen M. Uchitelle 提交于
      Remove assumption that a primary config exists
      e95edb3d
    • E
      Merge pull request #39535 from eileencodes/fix-schema-cache-test · 154a84af
      Eileen M. Uchitelle 提交于
      Fix schema cache load and corresponding test
      154a84af
    • V
      Expand on specs of self join and add make doc changes to suggest users to also... · e07d10d5
      Vipul A M 提交于
      Expand on specs of self join and add make doc changes to suggest users to also do  foreign_key when doing self join
      e07d10d5
    • E
      Fix schema cache load and corresponding test · e7b1e118
      eileencodes 提交于
      This test was incorrect. `primary` was winning for the schema cache load
      but when you boot an application it's actually the first configuration
      that wins (in a multi db app).
      
      The test didn't catch this because I forgot to add a migrations_paths to
      the configuration.
      
      We updated the schema cache loader railtie as well because any
      application that didn't have a `primary` config would not be able to use
      the schema cache. Originally we thought we'd enforce a `primary`
      configuration but no longer feel that's correct. It's simpler to say
      that the first wins in a 3-tier rather than implementing a solution to
      require `primary` and / or allow aliases.
      Co-authored-by: NJohn Crepezzi <john.crepezzi@gmail.com>
      Co-authored-by: NJohn Hawthorn <john@hawthorn.email>
      e7b1e118
    • E
      Remove assumption that a primary config exists · 7b4fdf3c
      eileencodes 提交于
      Applications may not have a primary configuration so we should not
      assume there is one. In both these cases we can get the right connection
      without that.
      
      For the databases.rake file we want to re-establish a connection for the
      environment we're in. The first config defined under an environment for
      a multi-db app will win. This is already the case on application boot so
      we should be consistent.
      
      For the info.rb file we already have a connection so we can lookup the
      adapter from the connection's db_config. If a primary hadn't existed
      this would have thrown an exception.
      
      Followup to https://github.com/rails/rails/pull/39535 which removed the
      assumption there was a primary config from the schema cache load
      railtie.
      Co-authored-by: NJohn Crepezzi <john.crepezzi@gmail.com>
      7b4fdf3c
  7. 04 6月, 2020 9 次提交