1. 24 7月, 2015 2 次提交
    • A
      Remove ivar only when defined · 430b7c8b
      Akira Matsuda 提交于
      this fixes a failing test case
      430b7c8b
    • R
      Improvements on the enum documentation [ci skip] · cdc32def
      Robin Dupret 提交于
      The note regarding the `_prefix` and `_suffix` options is no longer
      useful since they were renamed specifically for this purpose.
      
      Also the given example doesn't show what these options enable and in
      which case they are really useful (when there are conflicting values
      for instance).
      
      Refs #20999.
      
      [Godfrey Chan & Robin Dupret]
      cdc32def
  2. 23 7月, 2015 2 次提交
  3. 22 7月, 2015 1 次提交
  4. 21 7月, 2015 3 次提交
    • S
      Extra caller details added to ActiveRecord::RecordNotFound · d763956e
      Sameer Rahmani 提交于
      ActiveRecord::RecordNotFound modified to store model name, primary_key
      and id of the caller model. It allows the catcher of this exception to make
      a better decision to what to do with it. For example consider this simple
      example:
      
          class SomeAbstractController < ActionController::Base
            rescue_from ActiveRecord::RecordNotFound, with: :redirect_to_404
      
            private def redirect_to_404(e)
              return redirect_to(posts_url) if e.model == 'Post'
              raise
            end
          end
      d763956e
    • R
      Deprecate and rename the keys for association restrict_dependent_destroy · b184398b
      Roque Pinel 提交于
      Previously `has_one` and `has_many` associations were using the
      `one` and `many` keys respectively. Both of these keys have special
      meaning in I18n (they are considered to be pluralizations) so by
      renaming them to `has_one` and `has_many` we make the messages more
      explicit and most importantly they don't clash with linguistical
      systems that need to validate translation keys (and their
      pluralizations).
      
      The `:'restrict_dependent_destroy.one'` key should be replaced with
      `:'restrict_dependent_destroy.has_one'`, and
      `:'restrict_dependent_destroy.many'` with
      `:'restrict_dependent_destroy.has_many'`.
      
      [Roque Pinel & Christopher Dell]
      b184398b
    • J
  5. 20 7月, 2015 8 次提交
    • S
      Fix minor typo in test name · 17b84600
      Sean Griffin 提交于
      17b84600
    • R
      Fix state being carried over from previous transaction · 12b0b26d
      Roque Pinel 提交于
      This clears the transaction record state when the transaction finishes
      with a `:committed` status.
      
      Considering the following example where `name` is a required attribute.
      Before we had `new_record?` returning `true` for a persisted record:
      
      ```ruby
        author = Author.create! name: 'foo'
        author.name = nil
        author.save        # => false
        author.new_record? # => true
      ```
      12b0b26d
    • S
      Correctly ignore `mark_for_destruction` without `autosave` · c0ef95a1
      Sean Griffin 提交于
      As per the docs, `mark_for_destruction` should do nothing if `autosave`
      is not set to true. We normally persist associations on a record no
      matter what if the record is a new record, but we were always skipping
      records which were `marked_for_destruction?`.
      
      Fixes #20882
      c0ef95a1
    • M
    • M
      1883f377
    • S
      Freeze string literals when not mutated. · 5bb1d4d2
      schneems 提交于
      I wrote a utility that helps find areas where you could optimize your program using a frozen string instead of a string literal, it's called [let_it_go](https://github.com/schneems/let_it_go). After going through the output and adding `.freeze` I was able to eliminate the creation of 1,114 string objects on EVERY request to [codetriage](codetriage.com). How does this impact execution?
      
      To look at memory:
      
      ```ruby
      require 'get_process_mem'
      
      mem = GetProcessMem.new
      GC.start
      GC.disable
      1_114.times { " " }
      before = mem.mb
      
      after = mem.mb
      GC.enable
      puts "Diff: #{after - before} mb"
      
      ```
      
      Creating 1,114 string objects results in `Diff: 0.03125 mb` of RAM allocated on every request. Or 1mb every 32 requests.
      
      To look at raw speed:
      
      ```ruby
      require 'benchmark/ips'
      
      number_of_objects_reduced = 1_114
      
      Benchmark.ips do |x|
        x.report("freeze")    { number_of_objects_reduced.times { " ".freeze } }
        x.report("no-freeze") { number_of_objects_reduced.times { " " } }
      end
      ```
      
      We get the results
      
      ```
      Calculating -------------------------------------
                    freeze     1.428k i/100ms
                 no-freeze   609.000  i/100ms
      -------------------------------------------------
                    freeze     14.363k (± 8.5%) i/s -     71.400k
                 no-freeze      6.084k (± 8.1%) i/s -     30.450k
      ```
      
      Now we can do some maths:
      
      ```ruby
      ips = 6_226k # iterations / 1 second
      call_time_before = 1.0 / ips # seconds per iteration 
      
      ips = 15_254 # iterations / 1 second
      call_time_after = 1.0 / ips # seconds per iteration 
      
      diff = call_time_before - call_time_after
      
      number_of_objects_reduced * diff * 100
      
      # => 0.4530373333993266 miliseconds saved per request
      ```
      
      So we're shaving off 1 second of execution time for every 220 requests. 
      
      Is this going to be an insane speed boost to any Rails app: nope. Should we merge it: yep. 
      
      p.s. If you know of a method call that doesn't modify a string input such as [String#gsub](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37) please [give me a pull request to the appropriate file](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37), or open an issue in LetItGo so we can track and freeze more strings. 
      
      Keep those strings Frozen
      
      ![](https://www.dropbox.com/s/z4dj9fdsv213r4v/let-it-go.gif?dl=1)
      5bb1d4d2
    • S
      Fix the test that was broken by #16445 rather than deleting it · 8cd1d5a4
      Sean Griffin 提交于
      Since the counter cache was properly being updated, the model became
      stale. Simply reloading the model before attempting to destroy is
      sufficient for this case. I believe this is enough of an edge case to be
      a valid change to the tests, even though it represents a potential
      breaking change.
      8cd1d5a4
    • S
      Fix counter_cache for polymorphic associations · 0ed096dd
      Stefan Kanev 提交于
      Also removes a false positive test that depends on the fixed bug:
      
      At this time, counter_cache does not work with polymorphic relationships
      (which is a bug). The test was added to make sure that no
      StaleObjectError is raised when the car is destroyed. No such error is
      currently raised because the lock version is not incremented by
      appending a wheel to the car.
      
      Furthermore, `assert_difference` succeeds because `car.wheels.count`
      does not check the counter cache, but the collection size. The test will
      fail if it is replaced with `car.wheels_count || 0`.
      0ed096dd
  6. 18 7月, 2015 4 次提交
    • T
    • S
      Ensure cyclic associations w/ autosave don't cause duplicate errors · 7550f0a0
      Sean Griffin 提交于
      This code is so fucked. Things that cause this bug not to replicate:
      
      - Defining the validation before the association (we end up calling
        `uniq!` on the errors in the autosave validation)
      - Adding `accepts_nested_attributes_for` (I have no clue why. The only
        thing it does that should affect this is adds `autosave: true` to the
        inverse reflection, and doing that manually doesn't fix this).
      
      This solution is a hack, and I'm almost certain there's a better way to
      go about it, but this shouldn't cause a huge hit on validation times,
      and is the simplest way to get it done.
      
      Fixes #20874.
      7550f0a0
    • S
      Ensure that `ActionController::Parameters` can still be passed to AR · 68af6361
      Sean Griffin 提交于
      Since nested hashes are also instances of
      `ActionController::Parameters`, and we're explicitly looking to work
      with a hash for nested attributes, this caused breakage in several
      points.
      
      This is the minimum viable fix for the issue (and one that I'm not
      terribly fond of). I can't think of a better place to handle this at the
      moment. I'd prefer to use some sort of solution that doesn't special
      case AC::Parameters, but we can't use something like `to_h` or `to_a`
      since `Enumerable` adds both.
      
      While I've added a trivial test case for verifying this fix in
      isolation, we really need better integration coverage to prevent
      regressions like this in the future. We don't actually have a lot of
      great places for integration coverage at the moment, so I'm deferring it
      for now.
      
      Fixes #20922.
      68af6361
    • A
      [ci skip] Fix typo in #any? RDoc · a8e11ff5
      Andrii Ponomarov 提交于
      a8e11ff5
  7. 17 7月, 2015 1 次提交
    • P
      Silence deprecation warning from force reload · b5b89796
      Prem Sichanugrist 提交于
      We deprecate the support for passing an argument to force reload in
      6eae366d. That led to several
      deprecation warning when running Active Record test suite.
      
      This commit silence the warnings by properly calling `#reload` on the
      association proxy or on the association object instead. However, there
      are several places that `ActiveSupport::Deprecation.silence` are used as
      those tests actually tests the force reload functionality and will be
      removed once `master` is targeted next minor release (5.1).
      b5b89796
  8. 16 7月, 2015 2 次提交
    • P
      Deprecate force association reload by passing true · 6eae366d
      Prem Sichanugrist 提交于
      This is to simplify the association API, as you can call `reload` on the
      association proxy or the parent object to get the same result.
      
      For collection association, you can call `#reload` on association proxy
      to force a reload:
      
          @user.posts.reload   # Instead of @user.posts(true)
      
      For singular association, you can call `#reload` on the parent object to
      clear its association cache then call the association method:
      
          @user.reload.profile   # Instead of @user.profile(true)
      
      Passing a truthy argument to force association to reload will be removed
      in Rails 5.1.
      6eae366d
    • 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
  9. 14 7月, 2015 1 次提交
    • J
      Replaced `ActiveSupport::Concurrency::Latch` with concurrent-ruby. · 284a9ba8
      Jerry D'Antonio 提交于
      The concurrent-ruby gem is a toolset containing many concurrency
      utilities. Many of these utilities include runtime-specific
      optimizations when possible. Rather than clutter the Rails codebase with
      concurrency utilities separate from the core task, such tools can be
      superseded by similar tools in the more specialized gem. This commit
      replaces `ActiveSupport::Concurrency::Latch` with
      `Concurrent::CountDownLatch`, which is functionally equivalent.
      284a9ba8
  10. 08 7月, 2015 1 次提交
    • R
      Fix regression caused by a01d164b · 1b4399df
      Rafael Mendonça França 提交于
      When preload is used in a default scope the preload_values were
      returning nested arrays and causing the preloader to fail because it
      doesn't know how to deal with nested arrays. So before calling preload!
      we need to splat the arguments.
      
      This is not needed to includes because it flatten its arguments.
      1b4399df
  11. 07 7月, 2015 2 次提交
  12. 03 7月, 2015 3 次提交
    • J
      [skip ci] #distinct instead of #uniq · 64401610
      Jon Atack 提交于
      as #uniq will be removed from Rails 5.0 as per the Active Support
      exception raised:
      
      ActiveSupport::DeprecationException: DEPRECATION WARNING: uniq is
      deprecated and will be removed from Rails 5.0 (use distinct instead).
      64401610
    • E
      Fix spelling of `Thoughtleadering` · cc7ef0cf
      eileencodes 提交于
      Not much of a thought leader if I can't spell it correctly 😉
      cc7ef0cf
    • E
      Use default model enum in fixtures if not defined · eff3a317
      eileencodes 提交于
      After 908cfef6 was introduced fixtures that did not set an enum would
      return nil instead of the default enum value.
      
      The fixtures should assume the default if a different enum is not
      defined.
      
      The change checks first if the enum is defined in the fixture before
      setting it based on the fixture.
      eff3a317
  13. 01 7月, 2015 1 次提交
    • S
      Correct through associations using scopes · bc6ac860
      Sean Griffin 提交于
      The changes introduced to through associations in c80487eb were quite
      interesting. Changing `relation.merge!(scope)` to `relation =
      relation.merge(scope)` should in theory never cause any changes in
      behavior. The subtle breakage led to a surprising conclusion.
      
      The old code wasn't doing anything! Since `merge!` calls
      `instance_exec` when given a proc, and most scopes will look something
      like `has_many :foos, -> { where(foo: :bar) }`, if we're not capturing
      the return value, it's a no-op. However, removing the `merge` causes
      `unscope` to break.
      
      While we're merging in the rest of the chain elsewhere, we were never
      merging in `unscope` values, causing a breakage on associations where a
      default scope was being unscoped in an association scope (yuk!). This is
      subtly related to #20722, since it appears we were previously relying on
      this mutability.
      
      Fixes #20721.
      Fixes #20727.
      bc6ac860
  14. 30 6月, 2015 2 次提交
  15. 29 6月, 2015 1 次提交
  16. 28 6月, 2015 1 次提交
    • S
      Revert the behavior of association names and `where` to be closer to 4.2 · 6a6c4c45
      Sean Griffin 提交于
      With this change, we will always assume the association name is the same
      as the table it's referencing. This is subtly different than treating
      the hash key passed to `where` as the table name, as it still allows the
      class referenced by the association to provide additional type
      information.
      
      After exploring several possible solutions to the ambiguity problem, I
      do not think there is a short term answer that will maintain backwards
      compatibility.
      
      This change will make it so the following code does not work:
      
          class User
            has_many :approved_posts, -> { where(approved: true) }, class_name: "Post"
          end
      
          User.where(approved_posts: { id: 1 })
      
      But prevents potential ambiguity and collision as demonstrated in [this
      gist](https://gist.github.com/senny/1ae4d8ea7b0e269ed7a0).
      
      Unfortunately, truely solving this requires significantly
      re-architecting this code, so that what is currently represented as an
      `Arel::Attribute` is instead another data structure that also references
      the association it is representing, so we can identify the proper table
      name for aliasing when we construct the final tree.
      
      While I'd still like to accomplish that in the long run, I don't think
      I'll be able to get there in time for Rails 5 (since I'm not full time
      OSS any more, and this is several weeks worth of work). I'm hoping to
      achieve this for Rails 5.1.
      
      Fixes #20308
      6a6c4c45
  17. 27 6月, 2015 2 次提交
    • P
      Update .pluck documentation on uniq · 03f35fc4
      Prem Sichanugrist 提交于
      This is to show users that they can chain `.uniq` and `.pluck` to get
      the `DISTINCT column` result. They don't have to do `DISTINCT column`
      themselves.
      03f35fc4
    • P
      Add reversible syntax for change_column_default · a4128725
      Prem Sichanugrist 提交于
      Passing `:from` and `:to` to `change_column_default` makes this command
      reversible as user has defined its previous state.
      
      So, instead of having the migration command as:
      
          change_column_default(:posts, :state, "draft")
      
      They can write it as:
      
          change_column_default(:posts, :state, from: nil, to: "draft")
      a4128725
  18. 25 6月, 2015 2 次提交
  19. 24 6月, 2015 1 次提交