1. 01 9月, 2018 1 次提交
    • E
      Convert configs_for to kwargs, add include_replicas · a572d228
      Eileen Uchitelle 提交于
      Changes the `configs_for` method from using traditional arguments to
      using kwargs. This is so I can add the `include_replicas` kwarg without
      having to always include `env_name` and `spec_name` in the method call.
      
      `include_replicas` defaults to false because everywhere internally in
      Rails we don't want replicas. `configs_for` is for iterating over
      configurations to create / run rake tasks, so we really don't ever need
      replicas in that case.
      a572d228
  2. 31 8月, 2018 7 次提交
  3. 30 8月, 2018 21 次提交
    • E
      Add migrations_paths option to migration generator · b551a707
      Eileen Uchitelle 提交于
      Adds an option to the migration generator to allow setting the
      migrations paths for that migration. This is useful for applications
      that use multiple databases and put migrations per database in their own
      directories.
      
      ```
      bin/rails g migration CreateHouses address:string --migrations-paths=db/kingston_migrate
            invoke  active_record
            create    db/kingston_migrate/20180830151055_create_houses.rb
      ```
      b551a707
    • R
      Refactor `attributes_for_{create,update}` to avoid an extra allocation · 5e86ee11
      Ryuta Kamizono 提交于
      Use `delete_if` instead of `reject` to avoid an extra allocation.
      5e86ee11
    • S
      Do not recompute length · 897c377b
      schneems 提交于
      We can get a speed gain by moving the length calculation and assignment out of the loop.
      897c377b
    • R
      Remove `attributes_with_values_for_{create,update}` for internal use · 56ca81a9
      Ryuta Kamizono 提交于
      `attributes_with_values_for_update` is no longer used since ae2d36cf, and
      `attributes_with_values_for_create` is internally used only one place.
      56ca81a9
    • E
      Refactors Active Record connection management · fdf3f0b9
      Eileen Uchitelle 提交于
      While the three-tier config makes it easier to define databases for
      multiple database applications, it quickly became clear to offer full
      support for multiple databases we need to change the way the connections
      hash was handled.
      
      A three-tier config means that when Rails needed to choose a default
      configuration (in the case a user doesn't ask for a specific
      configuration) it wasn't clear to Rails which the default was. I
      [bandaid fixed this so the rake tasks could work](#32271) but that fix
      wasn't correct because it actually doubled up the configuration hashes.
      
      Instead of attemping to manipulate the hashes @tenderlove and I decided
      that it made more sense if we converted the hashes to objects so we can
      easily ask those object questions. In a three tier config like this:
      
      ```
      development:
        primary:
          database: "my_primary_db"
        animals:
          database; "my_animals_db"
      ```
      
      We end up with an object like this:
      
      ```
        @configurations=[
          #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
            @env_name="development",@spec_name="primary",
            @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>,
          #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90
            @env_name="development",@spec_name="animals",
            @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
      ]>
      ```
      
      The configurations setter takes the database configuration set by your
      application and turns them into an
      `ActiveRecord::DatabaseConfigurations` object that has one getter -
      `@configurations` which is an array of all the database objects.
      
      The configurations getter returns this object by default since it acts
      like a hash in most of the cases we need. For example if you need to
      access the default `development` database we can simply request it as we
      did before:
      
      ```
      ActiveRecord::Base.configurations["development"]
      ```
      
      This will return primary development database configuration hash:
      
      ```
      { "database" => "my_primary_db" }
      ```
      
      Internally all of Active Record has been converted to use the new
      objects. I've built this to be backwards compatible but allow for
      accessing the hash if needed for a deprecation period. To get the
      original hash instead of the object you can either add `to_h` on the
      configurations call or pass `legacy: true` to `configurations.
      
      ```
      ActiveRecord::Base.configurations.to_h
      => { "development => { "database" => "my_primary_db" } }
      
      ActiveRecord::Base.configurations(legacy: true)
      => { "development => { "database" => "my_primary_db" } }
      ```
      
      The new configurations object allows us to iterate over the Active
      Record configurations without losing the known environment or
      specification name for that configuration. You can also select all the
      configs for an env or env and spec. With this we can always ask
      any object what environment it belongs to:
      
      ```
      db_configs = ActiveRecord::Base.configurations.configurations_for("development")
      => #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800
        @configurations=[
          #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
            @env_name="development",@spec_name="primary",
            @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>,
          #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90
            @env_name="development",@spec_name="animals",
            @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
      ]>
      
      db_config.env_name
      => "development"
      
      db_config.spec_name
      => "primary"
      
      db_config.config
      => { "adapter"=>"sqlite3", "database"=>"db/development.sqlite3" }
      ```
      
      The configurations object is more flexible than the configurations hash
      and will allow us to build on top of the connection management in order
      to add support for primary/replica connections, sharding, and
      constructing queries for associations that live in multiple databases.
      fdf3f0b9
    • R
    • R
      Merge pull request #33757 from bogdanvlviv/follow-up-32937 · 9297af5d
      Ryuta Kamizono 提交于
      Follow up #32937 [ci skip]
      9297af5d
    • B
    • B
      Add info about `config.action_dispatch.use_cookies_with_metadata` to... · 35740ab2
      bogdanvlviv 提交于
      Add info about `config.action_dispatch.use_cookies_with_metadata` to "Configuring Rails Applications" guide [ci skip]
      
      Related to #32937, #33605.
      35740ab2
    • B
      Fix `actionpack/CHANGELOG.md` [ci skip] · 3175d3d5
      bogdanvlviv 提交于
      Remove the reference to the PR.
      Usually, we write reference to solved issues in the changelog files.
      Related to #33605.
      
      Add missing dots.
      
      Improve formatting.
      3175d3d5
    • Y
      Add missing require · fa132efe
      yuuji.yaginuma 提交于
      Without this, `inverse_associations_test.rb` breaks when running in isolation.
      https://travis-ci.org/rails/rails/jobs/422266840#L1894-L1899
      fa132efe
    • R
      Merge pull request #33729 from kddeisz/plural-automatic-inverse · ed1eda27
      Rafael França 提交于
      Find inverse associations with plural names
      ed1eda27
    • R
      Merge pull request #33752 from sgrif/sg-faster-try · 3d2caab7
      Richard Schneeman 提交于
      20% faster `try`
      3d2caab7
    • R
      Merge pull request #33737 from bogdanvlviv/add-6_0_release_notes-guide · aab0c25f
      Rafael França 提交于
      Add "Ruby on Rails 6.0 Release Notes" guide [ci skip]
      aab0c25f
    • S
      20% faster `try` · 0f462da8
      Sean Griffin 提交于
      Following up on #33747, this takes things a step further by pulling out
      the method name from the arguments array, letting us skip an allocation
      in the case where there are no arguments -- notably, this also no longer
      *requires* the splat to be an array, allowing us to benefit from
      optimizations in Jruby (and maybe MRI in the future) of skipping the
      array allocation entirely.
      
      Benchmark results:
      
      ```
      Warming up --------------------------------------
                       old   179.987k i/100ms
                       new   199.201k i/100ms
      Calculating -------------------------------------
                       old      3.029M (± 1.6%) i/s -     15.299M in   5.052417s
                       new      3.657M (± 1.2%) i/s -     18.326M in   5.012648s
      
      Comparison:
                       new:  3656620.7 i/s
                       old:  3028848.3 i/s - 1.21x  slower
      ```
      0f462da8
    • R
      Merge pull request #33744 from bogdanvlviv/fixes-27852 · cc81cd35
      Ryuta Kamizono 提交于
      Prevent leaking of user's DB credentials on `rails db:create` failure
      cc81cd35
    • R
      Merge pull request #33749 from schneems/schneems/faster-fragment · 0d63712f
      Richard Schneeman 提交于
      Fewer allocations in caching/fragments.rb
      0d63712f
    • R
      Merge pull request #33750 from schneems/schneems/time_value · 0d0f48a2
      Richard Schneeman 提交于
      Faster time_value.rb
      0d0f48a2
    • S
      Faster time_value.rb · e81b0ddd
      schneems 提交于
      The multiplication of the value takes a long time when we can instead mutate and use the string value directly.
      
      The `microsec` perf increases speed by 27% in the ideal case (which is the most common).
      
      ```
      original_string = ".443959"
      
      require 'benchmark/ips'
      
      Benchmark.ips do |x|
        x.report("multiply") { 
          string = original_string.dup
          (string.to_r * 1_000_000).to_i 
        }
        x.report("new     ") { 
          string = original_string.dup
          if string && string.start_with?(".".freeze) && string.length == 7
            string[0] = ''.freeze
            string.to_i
          end
        }
        x.compare!
      end
      
      # Warming up --------------------------------------
      #             multiply   125.783k i/100ms
      #             new        146.543k i/100ms
      # Calculating -------------------------------------
      #             multiply      1.751M (± 3.3%) i/s -      8.805M in   5.033779s
      #             new           2.225M (± 2.1%) i/s -     11.137M in   5.007110s
      
      # Comparison:
      #             new     :  2225289.7 i/s
      #             multiply:  1751254.2 i/s - 1.27x  slower
      ```
      e81b0ddd
    • R
      Merge pull request #33747 from schneems/schneems/faster-try · 96d7504d
      Richard Schneeman 提交于
      32% Faster Object#try
      96d7504d
    • E
      Remove this conditional · a64dba1d
      Eileen Uchitelle 提交于
      I removed the argument so I should remove the conditional too.
      a64dba1d
  4. 29 8月, 2018 11 次提交
    • E
      Remove unused argument · c91f1482
      Eileen Uchitelle 提交于
      The test that used this was updated and it's no longer needed.
      c91f1482
    • E
      Merge pull request #33748 from eileencodes/fix-erb-loading-issue-with-db-yaml · 55133a0e
      Eileen M. Uchitelle 提交于
      Drop load_database_yaml and fix test
      55133a0e
    • S
      32% Faster Object#try · ba7d1265
      schneems 提交于
      Here’s the micro benchmark:
      
      ```ruby
      module ActiveSupport
        module NewTryable #:nodoc:
          def try(*a, &b)
            return unless a.empty? || respond_to?(a.first)
            return public_send(*a, &b) unless a.empty?
      
            return nil unless block_given?
            return instance_eval(&b) if b.arity == 0
            yield self
          end
      
          def try!(*a, &b)
            return public_send(*a, &b) if !a.empty?
            return nil unless block_given?
            return instance_eval(&b) if b.arity == 0
            yield self
          end
        end
      end
      
      
      module ActiveSupport
        module OldTryable #:nodoc:
          def try(*a, &b)
            try!(*a, &b) if a.empty? || respond_to?(a.first)
          end
      
          def try!(*a, &b)
            if a.empty? && block_given?
              if b.arity == 0
                instance_eval(&b)
              else
                yield self
              end
            else
              public_send(*a, &b)
            end
          end
        end
      end
      
      class FooNew
        include ActiveSupport::NewTryable
      
        def foo
        end
      end
      
      class FooOld
        include ActiveSupport::OldTryable
      
        def foo
        end
      end 
      
      
      foo_new = FooNew.new
      foo_old = FooOld.new
      
      require 'benchmark/ips'
      
      Benchmark.ips do |x|
        x.report("old") { foo_old.try(:foo) }
        x.report("new") { foo_new.try(:foo) }
        x.compare!
      end
      
      # Warming up --------------------------------------
      #                  old   144.178k i/100ms
      #                  new   172.371k i/100ms
      # Calculating -------------------------------------
      #                  old      2.181M (± 8.0%) i/s -     10.813M in   5.001419s
      #                  new      2.889M (± 7.7%) i/s -     14.479M in   5.051760s
      
      # Comparison:
      #                  new:  2888691.7 i/s
      #                  old:  2180740.7 i/s - 1.32x  slower
      ```
      
      Also reduces memory. On https://www.codetriage.com i’m seeing 1.5% fewer object allocations per request (in object count).
      
      Before:
      
      Total allocated: 1014475 bytes (8525 objects)
      
      After:
      
      Total allocated: 1015499 bytes (8389 objects)
      ba7d1265
    • S
      Fewer allocations in caching/fragments.rb · e92adb3d
      schneems 提交于
      Instead of using a splat on the head and tail we can mutate the array by flattening 1 level. We get further savings by not allocating another via `compact` but instead by using `compact!`
      e92adb3d
    • E
      Drop load_database_yaml and fix test · 6b5df90f
      Eileen Uchitelle 提交于
      We originally did the whole `load_database_yaml` thing because this test
      wasn't cooperating and we needed to finish the namespaced rake tasks for
      multiple databases.
      
      However, it turns out that YAML can't eval ERB if you don't tell it it's
      ERB so you get Pysch parse errors if you're using multi-line ERB or
      ERB with conditionals. It's a hot mess.
      
      After trying a few things and thinking it over we decided that it wasn't
      worth bandaiding over, the test needed to be improved. The test was
      added in #31135 to test that the env is loaded in these tasks. But it
      was blowing up because we were trying to read a database name out of the
      configuration - however that's not the purpose of this change. We want
      to read environment files in the rake tasks, but not in the config
      file.
      
      In this PR we changed the test to test what the PR was actually fixing.
      We've also deleted the `load_database_yaml` because it caused more
      problems than it was worth. This should fix the issues described in
      https://github.com/rails/rails/pull/32274#issuecomment-384161057. We
      also had these problems at GitHub.
      Co-authored-by: Nalimi <aibrahim2k2@gmail.com>
      6b5df90f
    • B
      Prevent leaking of user's DB credentials on `rails db:create` failure · 9b455fe6
      bogdanvlviv 提交于
      Issue #27852 reports that when `rails db:create` fails, it causes
      leaking of user's DB credentials to $stderr.
      We print a DB's configuration hash in order to help users more quickly
      to figure out what could be wrong with his configuration.
      
      This commit changes message from
      "Couldn't create database for #{configuration.inspect}" to
      "Couldn't create '#{configuration['database']}' database. Please check your configuration.".
      
      There are two PRs that fixing it #27878, #27879, but they need a bit more work.
      I decided help to finish this and added Author of those PRs credit in this commit.
      
      Since it is a security issue, I think we should backport it to
      `5-2-stable`, and `5-1-stable`.
      Guided by https://edgeguides.rubyonrails.org/maintenance_policy.html#security-issues
      
      Fixes #27852
      Closes #27879
      Related to #27878
      
      [Alexander Marrs & bogdanvlviv]
      9b455fe6
    • B
      Add "Ruby on Rails 6.0 Release Notes" guide [ci skip] · 02fa55ac
      bogdanvlviv 提交于
      This commit adds a skeleton of "Ruby on Rails 6.0 Release Notes".
      It isn't a good time to add changelogs' entries to this guide since we can
      redo/revert some things till the final release 6.0.
      It would be better to do it close to the release.
      But we already can add mentions about major features
      that have been added to 6.0. I added mention about "Parallel Testing".
      02fa55ac
    • M
      Merge pull request #33718 from kddeisz/permit-list · 068fe7dc
      Matthew Draper 提交于
      Finish converting whitelist and blacklist references
      068fe7dc
    • Y
      Generate the same value as a label of view in system test template · 28e50850
      yuuji.yaginuma 提交于
      In the system test template, enter a value based on label.
      However, since `label` method does not use `titleize` by default.
      If generate a value including underscore, cannot find a label and the test
      will fail.
      
      ```
      $ ./bin/rails g scaffold user name:string phone_number:string
      $ ./bin/rails t test/system/users_test.rb
      
      E
      
      Error:
      UsersTest#test_creating_a_User:
      Capybara::ElementNotFound: Unable to find field "Phone Number"
          test/system/users_test.rb:18:in `block in <class:UsersTest>'
      ```
      
      This removes unnecessary `titleize` so that the generated file will pass
      even if the attribute contains an underscore.
      28e50850
    • R
    • J
      538f4290