From e0cb21f5f767606ad3ecf2db33855d27aa9f083d Mon Sep 17 00:00:00 2001
From: Tristan Gamilis <tristan@2suggestions.com.au>
Date: Tue, 7 Apr 2015 17:50:32 +1000
Subject: Require explicit counter_cache option for has_many

Previously has_many associations assumed a counter_cache was to be used
based on the presence of an appropriately named column. This is
inconsistent, since the inverse belongs_to association will not make
this assumption. See issues #19042 #8446.
This commit checks for the presence of the counter_cache key in the
options of either the has_many or belongs_to association as well as
ensuring that the *_count column is present.
---
 .../lib/active_record/associations/has_many_association.rb       | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index ca27c9fdde..794eb9e183 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -80,8 +80,15 @@ module ActiveRecord
           [association_scope.limit_value, count].compact.min
         end
 
+
+        # Returns whether a counter cache should be used for this association.
+        #
+        # The counter_cache option must be given on either the owner or inverse
+        # association, and the column must be present on the owner.
         def has_cached_counter?(reflection = reflection())
-          owner.attribute_present?(cached_counter_attribute_name(reflection))
+          if reflection.options[:counter_cache] || (inverse = inverse_which_updates_counter_cache(reflection)) && inverse.options[:counter_cache]
+            owner.attribute_present?(cached_counter_attribute_name(reflection))
+          end
         end
 
         def cached_counter_attribute_name(reflection = reflection())
-- 
cgit v1.2.3


From 929fcd26179f2b589d52f9515cbd349f1197ece9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mehmet=20Emin=20=C4=B0NA=C3=87?= <mehmetemininac@gmail.com>
Date: Wed, 15 Apr 2015 21:00:09 +0300
Subject: Prevent duplicating `where` clauses when model is extended from an
 abstract class Fixes #19528

fix for mysql2 test

better test
---
 activerecord/lib/active_record/scoping/default.rb | 1 +
 1 file changed, 1 insertion(+)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/scoping/default.rb b/activerecord/lib/active_record/scoping/default.rb
index 3590b8846e..a1adf8e3ee 100644
--- a/activerecord/lib/active_record/scoping/default.rb
+++ b/activerecord/lib/active_record/scoping/default.rb
@@ -100,6 +100,7 @@ module ActiveRecord
         end
 
         def build_default_scope(base_rel = relation) # :nodoc:
+          return if abstract_class?
           if !Base.is_a?(method(:default_scope).owner)
             # The user has defined their own default scope method, so call that
             evaluate_default_scope { default_scope }
-- 
cgit v1.2.3


From 7f2037a990fd81e07f612169f72e8d59fc2a4e52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mehmet=20Emin=20=C4=B0NA=C3=87?= <mehmetemininac@gmail.com>
Date: Mon, 8 Jun 2015 10:57:03 +0300
Subject: Add missing data types for ActiveRecord migrations

---
 .../postgresql/schema_definitions.rb               | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb
index 022dbdfa27..6399bddbee 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb
@@ -103,6 +103,30 @@ module ActiveRecord
           args.each { |name| column(name, :point, options) }
         end
 
+        def line(*args, **options)
+          args.each { |name| column(name, :line, options) }
+        end
+
+        def lseg(*args, **options)
+          args.each { |name| column(name, :lseg, options) }
+        end
+
+        def box(*args, **options)
+          args.each { |name| column(name, :box, options) }
+        end
+
+        def path(*args, **options)
+          args.each { |name| column(name, :path, options) }
+        end
+
+        def polygon(*args, **options)
+          args.each { |name| column(name, :polygon, options) }
+        end
+
+        def circle(*args, **options)
+          args.each { |name| column(name, :circle, options) }
+        end
+
         def serial(*args, **options)
           args.each { |name| column(name, :serial, options) }
         end
-- 
cgit v1.2.3


From beb07fbfae845d20323a9863c7216c6b63aff9c7 Mon Sep 17 00:00:00 2001
From: Guo Xiang Tan <tgx_world@hotmail.com>
Date: Wed, 15 Jul 2015 22:00:36 +0800
Subject: Revert "Revert "Reduce allocations when running AR callbacks.""
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit bdc1d329d4eea823d07cf010064bd19c07099ff3.

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: 'bdc1d329d4eea823d07cf010064bd19c07099ff3'
  gem 'rails', github: 'rails/rails', ref: 'd2876141d08341ec67cf6a11a073d1acfb920de7'
  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}"
```
---
 .../associations/has_many_through_association.rb             |  2 +-
 activerecord/lib/active_record/callbacks.rb                  | 11 ++++++-----
 .../connection_adapters/abstract/connection_pool.rb          |  4 ++--
 activerecord/lib/active_record/core.rb                       |  8 ++++----
 activerecord/lib/active_record/transactions.rb               | 12 ++++++------
 5 files changed, 19 insertions(+), 18 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index cd79266952..1aa6a2ca74 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -133,7 +133,7 @@ module ActiveRecord
             if scope.klass.primary_key
               count = scope.destroy_all.length
             else
-              scope.each { |record| record.run_callbacks :destroy }
+              scope.each(&:_run_destroy_callbacks)
 
               arel = scope.arel
 
diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb
index 3027ce928e..19f0dca5a6 100644
--- a/activerecord/lib/active_record/callbacks.rb
+++ b/activerecord/lib/active_record/callbacks.rb
@@ -289,24 +289,25 @@ module ActiveRecord
     end
 
     def destroy #:nodoc:
-      run_callbacks(:destroy) { super }
+      _run_destroy_callbacks { super }
     end
 
     def touch(*) #:nodoc:
-      run_callbacks(:touch) { super }
+      _run_touch_callbacks { super }
     end
 
   private
+
     def create_or_update(*) #:nodoc:
-      run_callbacks(:save) { super }
+      _run_save_callbacks { super }
     end
 
     def _create_record #:nodoc:
-      run_callbacks(:create) { super }
+      _run_create_callbacks { super }
     end
 
     def _update_record(*) #:nodoc:
-      run_callbacks(:update) { super }
+      _run_update_callbacks { super }
     end
   end
 end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index 6535121075..282af220fb 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -508,7 +508,7 @@ module ActiveRecord
         synchronize do
           remove_connection_from_thread_cache conn
 
-          conn.run_callbacks :checkin do
+          conn._run_checkin_callbacks do
             conn.expire
           end
 
@@ -764,7 +764,7 @@ module ActiveRecord
       end
 
       def checkout_and_verify(c)
-        c.run_callbacks :checkout do
+        c._run_checkout_callbacks do
           c.verify!
         end
         c
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 8a014e682e..b82488a59c 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -303,7 +303,7 @@ module ActiveRecord
       assign_attributes(attributes) if attributes
 
       yield self if block_given?
-      run_callbacks :initialize
+      _run_initialize_callbacks
     end
 
     # Initialize an empty model object from +coder+. +coder+ should be
@@ -330,8 +330,8 @@ module ActiveRecord
 
       self.class.define_attribute_methods
 
-      run_callbacks :find
-      run_callbacks :initialize
+      _run_find_callbacks
+      _run_initialize_callbacks
 
       self
     end
@@ -367,7 +367,7 @@ module ActiveRecord
       @attributes = @attributes.dup
       @attributes.reset(self.class.primary_key)
 
-      run_callbacks(:initialize)
+      _run_initialize_callbacks
 
       @new_record  = true
       @destroyed   = false
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 6f2def0df1..3131723828 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -319,8 +319,8 @@ module ActiveRecord
     end
 
     def before_committed! # :nodoc:
-      run_callbacks :before_commit_without_transaction_enrollment
-      run_callbacks :before_commit
+      _run_before_commit_without_transaction_enrollment_callbacks
+      _run_before_commit_callbacks
     end
 
     # Call the +after_commit+ callbacks.
@@ -329,8 +329,8 @@ module ActiveRecord
     # but call it after the commit of a destroyed object.
     def committed!(should_run_callbacks: true) #:nodoc:
       if should_run_callbacks && destroyed? || persisted?
-        run_callbacks :commit_without_transaction_enrollment
-        run_callbacks :commit
+        _run_commit_without_transaction_enrollment_callbacks
+        _run_commit_callbacks
       end
     ensure
       force_clear_transaction_record_state
@@ -340,8 +340,8 @@ module ActiveRecord
     # state should be rolled back to the beginning or just to the last savepoint.
     def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
       if should_run_callbacks
-        run_callbacks :rollback
-        run_callbacks :rollback_without_transaction_enrollment
+        _run_rollback_callbacks
+        _run_rollback_without_transaction_enrollment_callbacks
       end
     ensure
       restore_transaction_record_state(force_restore_state)
-- 
cgit v1.2.3


From 6eae366d0d2e5d5211eeaf955f56bd1dc6836758 Mon Sep 17 00:00:00 2001
From: Prem Sichanugrist <s@sikac.hu>
Date: Wed, 15 Jul 2015 14:07:45 -0400
Subject: Deprecate force association reload by passing true

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.
---
 .../lib/active_record/associations/collection_association.rb      | 8 ++++++++
 .../lib/active_record/associations/singular_association.rb        | 8 ++++++++
 2 files changed, 16 insertions(+)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 6caadb4ce8..87576abd92 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -1,3 +1,5 @@
+require "active_support/deprecation"
+
 module ActiveRecord
   module Associations
     # = Active Record Association Collection
@@ -28,6 +30,12 @@ module ActiveRecord
       # Implements the reader method, e.g. foo.items for Foo.has_many :items
       def reader(force_reload = false)
         if force_reload
+          ActiveSupport::Deprecation.warn(<<-MSG.squish)
+            Passing an argument to force an association to reload is now
+            deprecated and will be removed in Rails 5.1. Please call `reload`
+            on the result collection proxy instead.
+          MSG
+
           klass.uncached { reload }
         elsif stale_target?
           reload
diff --git a/activerecord/lib/active_record/associations/singular_association.rb b/activerecord/lib/active_record/associations/singular_association.rb
index bec9505bd2..30c5d72482 100644
--- a/activerecord/lib/active_record/associations/singular_association.rb
+++ b/activerecord/lib/active_record/associations/singular_association.rb
@@ -1,9 +1,17 @@
+require "active_support/deprecation"
+
 module ActiveRecord
   module Associations
     class SingularAssociation < Association #:nodoc:
       # Implements the reader method, e.g. foo.bar for Foo.has_one :bar
       def reader(force_reload = false)
         if force_reload && klass
+          ActiveSupport::Deprecation.warn(<<-MSG.squish)
+            Passing an argument to force an association to reload is now
+            deprecated and will be removed in Rails 5.1. Please call `reload`
+            on the parent object instead.
+          MSG
+
           klass.uncached { reload }
         elsif !loaded? || stale_target?
           reload
-- 
cgit v1.2.3


From a8e11ff5285c31c91255acfb462e731c1255c080 Mon Sep 17 00:00:00 2001
From: Andrii Ponomarov <andrii.ponomarov@gmail.com>
Date: Fri, 17 Jul 2015 21:03:49 -0400
Subject: [ci skip] Fix typo in #any? RDoc

---
 activerecord/lib/active_record/associations/collection_proxy.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index ddeafb40ea..19e9ffcb3c 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -781,7 +781,7 @@ module ActiveRecord
       #   person.pets.any?  # => false
       #
       #   person.pets << Pet.new(name: 'Snoop')
-      #   person.pets.count # => 0
+      #   person.pets.count # => 1
       #   person.pets.any?  # => true
       #
       # You can also pass a +block+ to define criteria. The behavior
-- 
cgit v1.2.3


From 68af63618223c238468af1afb093eb4ccc706761 Mon Sep 17 00:00:00 2001
From: Sean Griffin <sean@thoughtbot.com>
Date: Sat, 18 Jul 2015 08:42:29 -0400
Subject: Ensure that `ActionController::Parameters` can still be passed to AR

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.
---
 activerecord/lib/active_record/nested_attributes.rb | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index c942d0e265..c337e1d18f 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -386,6 +386,9 @@ module ActiveRecord
     # then the existing record will be marked for destruction.
     def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
       options = self.nested_attributes_options[association_name]
+      if attributes.respond_to?(:permitted?)
+        attributes = attributes.to_h
+      end
       attributes = attributes.with_indifferent_access
       existing_record = send(association_name)
 
-- 
cgit v1.2.3


From 7550f0a016ee6647aaa76c0c0ae30bebc3867288 Mon Sep 17 00:00:00 2001
From: Sean Griffin <sean@thoughtbot.com>
Date: Sat, 18 Jul 2015 10:28:24 -0400
Subject: Ensure cyclic associations w/ autosave don't cause duplicate errors

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.
---
 activerecord/lib/active_record/autosave_association.rb | 7 +++++++
 1 file changed, 7 insertions(+)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index 0792d19c3e..5f38bd51f6 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -222,6 +222,7 @@ module ActiveRecord
               true
             end
             validate validation_method
+            after_validation :_ensure_no_duplicate_errors
           end
         end
     end
@@ -456,5 +457,11 @@ module ActiveRecord
           end
         end
       end
+
+      def _ensure_no_duplicate_errors
+        errors.messages.each_key do |attribute|
+          errors[attribute].uniq!
+        end
+      end
   end
 end
-- 
cgit v1.2.3


From b5d4dd47deaae27e8f362bb9636246c5b4c56e5c Mon Sep 17 00:00:00 2001
From: Thomas Walpole <twalpole@gmail.com>
Date: Sat, 18 Jul 2015 08:23:52 -0700
Subject: Ensure that 'ActionController::Parameters' can still be passed to AR
 for collection associations

---
 activerecord/lib/active_record/nested_attributes.rb | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index c337e1d18f..a6b76b25bf 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -445,6 +445,9 @@ module ActiveRecord
     #   ])
     def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
       options = self.nested_attributes_options[association_name]
+      if attributes_collection.respond_to?(:permitted?)
+        attributes_collection = attributes_collection.to_h
+      end
 
       unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
         raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
@@ -471,6 +474,9 @@ module ActiveRecord
       end
 
       attributes_collection.each do |attributes|
+        if attributes.respond_to?(:permitted?)
+          attributes = attributes.to_h
+        end
         attributes = attributes.with_indifferent_access
 
         if attributes['id'].blank?
-- 
cgit v1.2.3


From 0ed096ddf5416fefa3afacb72c64632c02826f95 Mon Sep 17 00:00:00 2001
From: Stefan Kanev <stefan.kanev@gmail.com>
Date: Sat, 9 Aug 2014 22:19:02 +0300
Subject: Fix counter_cache for polymorphic associations

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`.
---
 .../lib/active_record/associations/builder/belongs_to.rb | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb
index 97eb007f62..6e4a53f7fb 100644
--- a/activerecord/lib/active_record/associations/builder/belongs_to.rb
+++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb
@@ -33,16 +33,24 @@ module ActiveRecord::Associations::Builder
 
           if (@_after_create_counter_called ||= false)
             @_after_create_counter_called = false
-          elsif attribute_changed?(foreign_key) && !new_record? && reflection.constructable?
-            model           = reflection.klass
+          elsif attribute_changed?(foreign_key) && !new_record?
+            if reflection.polymorphic?
+              model     = attribute(reflection.foreign_type).try(:constantize)
+              model_was = attribute_was(reflection.foreign_type).try(:constantize)
+            else
+              model     = reflection.klass
+              model_was = reflection.klass
+            end
+
             foreign_key_was = attribute_was foreign_key
             foreign_key     = attribute foreign_key
 
             if foreign_key && model.respond_to?(:increment_counter)
               model.increment_counter(cache_column, foreign_key)
             end
-            if foreign_key_was && model.respond_to?(:decrement_counter)
-              model.decrement_counter(cache_column, foreign_key_was)
+
+            if foreign_key_was && model_was.respond_to?(:decrement_counter)
+              model_was.decrement_counter(cache_column, foreign_key_was)
             end
           end
         end
-- 
cgit v1.2.3


From 5bb1d4d288d019e276335465d0389fd2f5246bfd Mon Sep 17 00:00:00 2001
From: schneems <richard.schneeman@gmail.com>
Date: Sun, 19 Jul 2015 16:19:15 -0500
Subject: Freeze string literals when not mutated.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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)
---
 activerecord/lib/active_record/attribute_methods.rb                 | 2 +-
 activerecord/lib/active_record/attribute_methods/read.rb            | 2 +-
 activerecord/lib/active_record/attribute_methods/write.rb           | 2 +-
 .../active_record/connection_adapters/postgresql/type_metadata.rb   | 2 +-
 activerecord/lib/active_record/relation/delegation.rb               | 2 +-
 activerecord/lib/active_record/relation/predicate_builder.rb        | 6 +++---
 6 files changed, 8 insertions(+), 8 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 9d58a19304..abe1d465a5 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -42,7 +42,7 @@ module ActiveRecord
 
       def [](name)
         @method_cache.compute_if_absent(name) do
-          safe_name = name.unpack('h*').first
+          safe_name = name.unpack('h*'.freeze).first
           temp_method = "__temp__#{safe_name}"
           ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
           @module.module_eval method_body(temp_method, safe_name), __FILE__, __LINE__
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index 0d989c2eca..2363cf7608 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -37,7 +37,7 @@ module ActiveRecord
         protected
 
         def define_method_attribute(name)
-          safe_name = name.unpack('h*').first
+          safe_name = name.unpack('h*'.freeze).first
           temp_method = "__temp__#{safe_name}"
 
           ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb
index ab017c7b54..07d5e7d38e 100644
--- a/activerecord/lib/active_record/attribute_methods/write.rb
+++ b/activerecord/lib/active_record/attribute_methods/write.rb
@@ -24,7 +24,7 @@ module ActiveRecord
         protected
 
         def define_method_attribute=(name)
-          safe_name = name.unpack('h*').first
+          safe_name = name.unpack('h*'.freeze).first
           ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
 
           generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb b/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb
index 58715978f7..b2c49989a4 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb
@@ -12,7 +12,7 @@ module ActiveRecord
       end
 
       def sql_type
-        super.gsub(/\[\]$/, "")
+        super.gsub(/\[\]$/, "".freeze)
       end
 
       def ==(other)
diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb
index 86f2c30168..d75ec72b1a 100644
--- a/activerecord/lib/active_record/relation/delegation.rb
+++ b/activerecord/lib/active_record/relation/delegation.rb
@@ -18,7 +18,7 @@ module ActiveRecord
           delegate = Class.new(klass) {
             include ClassSpecificRelation
           }
-          const_set klass.name.gsub('::', '_'), delegate
+          const_set klass.name.gsub('::'.freeze, '_'.freeze), delegate
           cache[klass] = delegate
         end
       end
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index 43e9afe853..d26db7d4cf 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -52,7 +52,7 @@ module ActiveRecord
           key
         else
           key = key.to_s
-          key.split('.').first if key.include?('.')
+          key.split('.'.freeze).first if key.include?('.'.freeze)
         end
       end.compact
     end
@@ -123,10 +123,10 @@ module ActiveRecord
     end
 
     def convert_dot_notation_to_hash(attributes)
-      dot_notation = attributes.keys.select { |s| s.include?(".") }
+      dot_notation = attributes.keys.select { |s| s.include?(".".freeze) }
 
       dot_notation.each do |key|
-        table_name, column_name = key.split(".")
+        table_name, column_name = key.split(".".freeze)
         value = attributes.delete(key)
         attributes[table_name] ||= {}
 
-- 
cgit v1.2.3


From 476e3f552f59d208cb284f509760b44ad780c17a Mon Sep 17 00:00:00 2001
From: "Alberto F. Capel" <afcapel@gmail.com>
Date: Tue, 14 Jul 2015 23:47:16 +0100
Subject: Add #cache_key to ActiveRecord::Relation.

---
 activerecord/lib/active_record.rb                  |  1 +
 activerecord/lib/active_record/base.rb             |  1 +
 .../lib/active_record/collection_cache_key.rb      | 29 ++++++++++++++++++++++
 activerecord/lib/active_record/relation.rb         | 26 +++++++++++++++++++
 4 files changed, 57 insertions(+)
 create mode 100644 activerecord/lib/active_record/collection_cache_key.rb

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb
index f5cf92db64..264f869c68 100644
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -53,6 +53,7 @@ module ActiveRecord
   autoload :Persistence
   autoload :QueryCache
   autoload :Querying
+  autoload :CollectionCacheKey
   autoload :ReadonlyAttributes
   autoload :RecordInvalid, 'active_record/validations'
   autoload :Reflection
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index c918e88590..55a7e053bc 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -280,6 +280,7 @@ module ActiveRecord #:nodoc:
     extend Explain
     extend Enum
     extend Delegation::DelegateCache
+    extend CollectionCacheKey
 
     include Core
     include Persistence
diff --git a/activerecord/lib/active_record/collection_cache_key.rb b/activerecord/lib/active_record/collection_cache_key.rb
new file mode 100644
index 0000000000..72b50c1d28
--- /dev/null
+++ b/activerecord/lib/active_record/collection_cache_key.rb
@@ -0,0 +1,29 @@
+module ActiveRecord
+  module CollectionCacheKey
+
+    def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc:
+      query_signature = Digest::MD5.hexdigest(collection.to_sql)
+      key = "#{collection.model_name.cache_key}/query-#{query_signature}"
+
+      if collection.loaded?
+        size = collection.size
+        timestamp = collection.max_by(&timestamp_column).public_send(timestamp_column)
+      else
+        column_type = type_for_attribute(timestamp_column.to_s)
+        column = "#{connection.quote_table_name(collection.table_name)}.#{connection.quote_column_name(timestamp_column)}"
+
+        query = collection.select("COUNT(*) AS size", "MAX(#{column}) AS timestamp")
+        result = connection.select_one(query)
+
+        size = result["size"]
+        timestamp = column_type.deserialize(result["timestamp"])
+      end
+
+      if timestamp
+        "#{key}-#{size}-#{timestamp.utc.to_s(cache_timestamp_format)}"
+      else
+        "#{key}-#{size}"
+      end
+    end
+  end
+end
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index e4df122af6..3ed04dee3b 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -298,6 +298,32 @@ module ActiveRecord
       limit_value ? to_a.many? : size > 1
     end
 
+    # Returns a cache key that can be used to identify the records fetched by
+    # this query. The cache key is built with a fingerprint of the sql query,
+    # the number of records matched by the query and a timestamp of the last
+    # updated record. When a new record comes to match the query, or any of
+    # the existing records is updated or deleted, the cache key changes.
+    #
+    #   Product.where("name like ?", "%Cosmic Encounter%").cache_key
+    #   => "products/query-1850ab3d302391b85b8693e941286659-1-20150714212553907087000"
+    #
+    # If the collection is loaded, the method will iterate through the records
+    # to generate the timestamp, otherwise it will trigger one SQL query like:
+    #
+    #    SELECT COUNT(*), MAX("products"."updated_at") FROM "products" WHERE (name like '%Cosmic Encounter%')
+    #
+    # You can also pass a custom timestamp column to fetch the timestamp of the
+    # last updated record.
+    #
+    #   Product.where("name like ?", "%Game%").cache_key(:last_reviewed_at)
+    #
+    # You can customize the strategy to generate the key on a per model basis
+    # overriding ActiveRecord::Base#collection_cache_key.
+    def cache_key(timestamp_column = :updated_at)
+      @cache_keys ||= {}
+      @cache_keys[timestamp_column] ||= @klass.collection_cache_key(self, timestamp_column)
+    end
+
     # Scope all queries to the current scope.
     #
     #   Comment.where(post_id: 1).scoping do
-- 
cgit v1.2.3


From 1883f37742b976d3d20e0ba4a3564911f4868172 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mehmet=20Emin=20=C4=B0NA=C3=87?= <mehmetemininac@gmail.com>
Date: Mon, 20 Jul 2015 10:58:59 +0300
Subject: Add missing method name to exception description

---
 activerecord/lib/active_record/associations/collection_proxy.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 19e9ffcb3c..b5a8c81fe4 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -971,7 +971,7 @@ module ActiveRecord
       alias_method :append, :<<
 
       def prepend(*args)
-        raise NoMethodError, "prepend on association is not defined. Please use << or append"
+        raise NoMethodError, "prepend on association is not defined. Please use <<, push or append"
       end
 
       # Equivalent to +delete_all+. The difference is that returns +self+, instead
-- 
cgit v1.2.3


From cc54f6be15d412b4fcb2a99d7bdf9244d756ce3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mehmet=20Emin=20=C4=B0NA=C3=87?= <mehmetemininac@gmail.com>
Date: Mon, 20 Jul 2015 11:11:24 +0300
Subject: fix doc about ActiveRecord::Transactions::ClassMethods#transaction
 [ci skip]

---
 activerecord/lib/active_record/transactions.rb | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 3131723828..267ac26c79 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -204,9 +204,8 @@ module ActiveRecord
     #
     # Note that "TRUNCATE" is also a MySQL DDL statement!
     module ClassMethods
-      # See ActiveRecord::Transactions::ClassMethods for detailed documentation.
+      # See the ConnectionAdapters::DatabaseStatements#transaction API docs.
       def transaction(options = {}, &block)
-        # See the ConnectionAdapters::DatabaseStatements#transaction API docs.
         connection.transaction(options, &block)
       end
 
-- 
cgit v1.2.3


From c0ef95a1c6db3095c4b5f80f8044fbbbdfebeff1 Mon Sep 17 00:00:00 2001
From: Sean Griffin <sean@thoughtbot.com>
Date: Mon, 20 Jul 2015 09:00:00 -0600
Subject: Correctly ignore `mark_for_destruction` without `autosave`

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
---
 activerecord/lib/active_record/autosave_association.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index 5f38bd51f6..dbb0e2fab2 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -325,7 +325,7 @@ module ActiveRecord
       # the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
       # enabled records if they're marked_for_destruction? or destroyed.
       def association_valid?(reflection, record)
-        return true if record.destroyed? || record.marked_for_destruction?
+        return true if record.destroyed? || (reflection.options[:autosave] && record.marked_for_destruction?)
 
         validation_context = self.validation_context unless [:create, :update].include?(self.validation_context)
         unless valid = record.valid?(validation_context)
-- 
cgit v1.2.3


From 12b0b26df7560ab5199ba830586864085441508f Mon Sep 17 00:00:00 2001
From: Roque Pinel <repinel@gmail.com>
Date: Sun, 19 Jul 2015 22:00:36 -0400
Subject: Fix state being carried over from previous transaction

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
```
---
 activerecord/lib/active_record/transactions.rb | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 267ac26c79..887d7a5903 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -379,6 +379,10 @@ module ActiveRecord
         raise ActiveRecord::Rollback unless status
       end
       status
+    ensure
+      if @transaction_state && @transaction_state.committed?
+        clear_transaction_record_state
+      end
     end
 
     protected
-- 
cgit v1.2.3


From e975d7cd1a6cb177f914024ffec8dd9a6cdc4ba1 Mon Sep 17 00:00:00 2001
From: Jori Hardman <jorihardman@gmail.com>
Date: Mon, 29 Jun 2015 11:37:05 -0500
Subject: Ensure that microsecond precision is only used for version of mysql
 that support it. Fixes #19711

---
 .../connection_adapters/abstract_adapter.rb            | 12 ++++++++++++
 .../connection_adapters/abstract_mysql_adapter.rb      | 18 +++++++++++++-----
 .../connection_adapters/sqlite3_adapter.rb             | 12 ------------
 3 files changed, 25 insertions(+), 17 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 6d3a21a3dc..56227ddd80 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -107,6 +107,18 @@ module ActiveRecord
         @prepared_statements = false
       end
 
+      class Version
+        include Comparable
+
+        def initialize(version_string)
+          @version = version_string.split('.').map(&:to_i)
+        end
+
+        def <=>(version_string)
+          @version <=> version_string.split('.').map(&:to_i)
+        end
+      end
+
       class BindCollector < Arel::Collectors::Bind
         def compile(bvs, conn)
           casted_binds = conn.prepare_binds_for_database(bvs)
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 2027492f29..af156c9c78 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -307,7 +307,7 @@ module ActiveRecord
       #
       # http://bugs.mysql.com/bug.php?id=39170
       def supports_transaction_isolation?
-        version[0] >= 5
+        version >= '5.0.0'
       end
 
       def supports_indexes_in_create?
@@ -319,11 +319,11 @@ module ActiveRecord
       end
 
       def supports_views?
-        version[0] >= 5
+        version >= '5.0.0'
       end
 
       def supports_datetime_with_precision?
-        (version[0] == 5 && version[1] >= 6) || version[0] >= 6
+        version >= '5.6.4'
       end
 
       def native_database_types
@@ -386,6 +386,14 @@ module ActiveRecord
         0
       end
 
+      def quoted_date(value)
+        if supports_datetime_with_precision?
+          super
+        else
+          super.sub(/\.\d{6}\z/, '')
+        end
+      end
+
       # REFERENTIAL INTEGRITY ====================================
 
       def disable_referential_integrity #:nodoc:
@@ -938,7 +946,7 @@ module ActiveRecord
       end
 
       def version
-        @version ||= full_version.scan(/^(\d+)\.(\d+)\.(\d+)/).flatten.map(&:to_i)
+        @version ||= Version.new(full_version.match(/^\d+\.\d+\.\d+/)[0])
       end
 
       def mariadb?
@@ -946,7 +954,7 @@ module ActiveRecord
       end
 
       def supports_rename_index?
-        mariadb? ? false : (version[0] == 5 && version[1] >= 7) || version[0] >= 6
+        mariadb? ? false : version >= '5.7.6'
       end
 
       def configure_connection
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 7c809b088c..358039723f 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -65,18 +65,6 @@ module ActiveRecord
         boolean:      { name: "boolean" }
       }
 
-      class Version
-        include Comparable
-
-        def initialize(version_string)
-          @version = version_string.split('.').map(&:to_i)
-        end
-
-        def <=>(version_string)
-          @version <=> version_string.split('.').map(&:to_i)
-        end
-      end
-
       class StatementPool < ConnectionAdapters::StatementPool
         private
 
-- 
cgit v1.2.3


From b184398b5359da5b76367aa61551d0f3d7e99fc5 Mon Sep 17 00:00:00 2001
From: Roque Pinel <repinel@gmail.com>
Date: Mon, 22 Jun 2015 22:28:57 -0400
Subject: Deprecate and rename the keys for association
 restrict_dependent_destroy

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]
---
 .../lib/active_record/associations/has_many_association.rb       | 9 ++++++++-
 .../lib/active_record/associations/has_one_association.rb        | 9 ++++++++-
 activerecord/lib/active_record/locale/en.yml                     | 4 ++--
 3 files changed, 18 insertions(+), 4 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index ca27c9fdde..9f6c832c1b 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -16,7 +16,14 @@ module ActiveRecord
         when :restrict_with_error
           unless empty?
             record = klass.human_attribute_name(reflection.name).downcase
-            owner.errors.add(:base, :"restrict_dependent_destroy.many", record: record)
+            message = owner.errors.generate_message(:base, :'restrict_dependent_destroy.many', record: record, raise: true) rescue nil
+            if message
+              ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
+                The error key `:'restrict_dependent_destroy.many'` has been deprecated and will be removed in Rails 5.1.
+                Please use `:'restrict_dependent_destroy.has_many'` instead.
+              MESSAGE
+            end
+            owner.errors.add(:base, message || :'restrict_dependent_destroy.has_many', record: record)
             throw(:abort)
           end
 
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
index 41a75b820e..5a92bc5e8a 100644
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -12,7 +12,14 @@ module ActiveRecord
         when :restrict_with_error
           if load_target
             record = klass.human_attribute_name(reflection.name).downcase
-            owner.errors.add(:base, :"restrict_dependent_destroy.one", record: record)
+            message = owner.errors.generate_message(:base, :'restrict_dependent_destroy.one', record: record, raise: true) rescue nil
+            if message
+              ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
+                The error key `:'restrict_dependent_destroy.one'` has been deprecated and will be removed in Rails 5.1.
+                Please use `:'restrict_dependent_destroy.has_one'` instead.
+              MESSAGE
+            end
+            owner.errors.add(:base, message || :'restrict_dependent_destroy.has_one', record: record)
             throw(:abort)
           end
 
diff --git a/activerecord/lib/active_record/locale/en.yml b/activerecord/lib/active_record/locale/en.yml
index 8a3c27e6da..0b35027b2b 100644
--- a/activerecord/lib/active_record/locale/en.yml
+++ b/activerecord/lib/active_record/locale/en.yml
@@ -16,8 +16,8 @@ en:
       messages:
         record_invalid: "Validation failed: %{errors}"
         restrict_dependent_destroy:
-          one: "Cannot delete record because a dependent %{record} exists"
-          many: "Cannot delete record because dependent %{record} exist"
+          has_one: "Cannot delete record because a dependent %{record} exists"
+          has_many: "Cannot delete record because dependent %{record} exist"
         # Append your own errors here or at the model/attributes scope.
 
       # You can define own errors for models or model attributes.
-- 
cgit v1.2.3


From d763956ed95bce581f12151a5ed4df12bcefdeee Mon Sep 17 00:00:00 2001
From: Sameer Rahmani <lxsameer@gnu.org>
Date: Tue, 21 Jul 2015 18:49:09 +0430
Subject: Extra caller details added to ActiveRecord::RecordNotFound

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
---
 activerecord/lib/active_record/core.rb                    | 8 +++++---
 activerecord/lib/active_record/errors.rb                  | 9 +++++++++
 activerecord/lib/active_record/nested_attributes.rb       | 4 +++-
 activerecord/lib/active_record/relation/finder_methods.rb | 3 ++-
 4 files changed, 19 insertions(+), 5 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index b82488a59c..ffce2173ec 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -162,11 +162,13 @@ module ActiveRecord
         }
         record = statement.execute([id], self, connection).first
         unless record
-          raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
+          raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
+                                   name, primary_key, id)
         end
         record
       rescue RangeError
-        raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
+        raise RecordNotFound.new("Couldn't find #{name} with an out of range value for '#{primary_key}'",
+                                 name, primary_key)
       end
 
       def find_by(*args) # :nodoc:
@@ -199,7 +201,7 @@ module ActiveRecord
       end
 
       def find_by!(*args) # :nodoc:
-        find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}")
+        find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}", name)
       end
 
       def initialize_generated_modules # :nodoc:
diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb
index 0f1759abaa..d589620f8a 100644
--- a/activerecord/lib/active_record/errors.rb
+++ b/activerecord/lib/active_record/errors.rb
@@ -47,6 +47,15 @@ module ActiveRecord
 
   # Raised when Active Record cannot find record by given id or set of ids.
   class RecordNotFound < ActiveRecordError
+    attr_reader :model, :primary_key, :id
+
+    def initialize(message = nil, model = nil, primary_key = nil, id = nil)
+      @primary_key = primary_key
+      @model = model
+      @id = id
+
+      super(message)
+    end
   end
 
   # Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index a6b76b25bf..c5a1488588 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -561,7 +561,9 @@ module ActiveRecord
     end
 
     def raise_nested_attributes_record_not_found!(association_name, record_id)
-      raise RecordNotFound, "Couldn't find #{self.class._reflect_on_association(association_name).klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
+      model = self.class._reflect_on_association(association_name).klass.name
+      raise RecordNotFound.new("Couldn't find #{model} with ID=#{record_id} for #{self.class.name} with ID=#{id}",
+                               model, 'id', record_id)
     end
   end
 end
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 9fef55adea..009b2bad57 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -85,7 +85,8 @@ module ActiveRecord
     def find_by!(arg, *args)
       where(arg, *args).take!
     rescue RangeError
-      raise RecordNotFound, "Couldn't find #{@klass.name} with an out of range value"
+      raise RecordNotFound.new("Couldn't find #{@klass.name} with an out of range value",
+                               @klass.name)
     end
 
     # Gives a record (or N records if a parameter is supplied) without any implied
-- 
cgit v1.2.3


From 4f1ec3ac96d4593063603306d2548e0206124d5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mehmet=20Emin=20=C4=B0NA=C3=87?= <mehmetemininac@gmail.com>
Date: Sun, 12 Jul 2015 03:03:05 +0300
Subject: Fix misleading errors for has_one through relations

---
 activerecord/lib/active_record/associations.rb           | 16 ++++++++++++++--
 .../active_record/associations/through_association.rb    | 12 ++++++++++--
 2 files changed, 24 insertions(+), 4 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 82cb3fed59..a830b0e0e4 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -61,12 +61,18 @@ module ActiveRecord
     end
   end
 
-  class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc:
+  class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc:
     def initialize(owner, reflection)
       super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.")
     end
   end
 
+  class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
+  end
+
+  class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
+  end
+
   class HasManyThroughCantAssociateNewRecords < ActiveRecordError #:nodoc:
     def initialize(owner, reflection)
       super("Cannot associate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to create the has_many :through record associating them.")
@@ -79,12 +85,18 @@ module ActiveRecord
     end
   end
 
-  class HasManyThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
+  class ThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
     def initialize(owner, reflection)
       super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
     end
   end
 
+  class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc:
+  end
+
+  class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc:
+  end
+
   class EagerLoadPolymorphicError < ActiveRecordError #:nodoc:
     def initialize(reflection)
       super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}")
diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb
index 55ee9f04e0..d0ec3e8015 100644
--- a/activerecord/lib/active_record/associations/through_association.rb
+++ b/activerecord/lib/active_record/associations/through_association.rb
@@ -76,13 +76,21 @@ module ActiveRecord
 
         def ensure_mutable
           unless source_reflection.belongs_to?
-            raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
+            if reflection.has_one?
+              raise HasOneThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
+            else
+              raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
+            end
           end
         end
 
         def ensure_not_nested
           if reflection.nested?
-            raise HasManyThroughNestedAssociationsAreReadonly.new(owner, reflection)
+            if reflection.has_one?
+              raise HasOneThroughNestedAssociationsAreReadonly.new(owner, reflection)
+            else
+              raise HasManyThroughNestedAssociationsAreReadonly.new(owner, reflection)
+            end
           end
         end
 
-- 
cgit v1.2.3


From a20965287caa59dae7360b74086c27ae945f94c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=BE=20=D0=91=D1=83=D0=B4?=
 =?UTF-8?q?=D0=BD=D0=B8=D0=BA?= <dmitriy.budnik@gmail.com>
Date: Thu, 23 Jul 2015 11:41:51 +0300
Subject: Fixes documentation typo.

Documentation had extra colon after keyword.
---
 .../active_record/connection_adapters/abstract/schema_statements.rb   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index e3115abe66..a30945d0ee 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -761,9 +761,9 @@ module ActiveRecord
       # [<tt>:name</tt>]
       #   The constraint name. Defaults to <tt>fk_rails_<identifier></tt>.
       # [<tt>:on_delete</tt>]
-      #   Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade:+ and +:restrict+
+      #   Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
       # [<tt>:on_update</tt>]
-      #   Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade:+ and +:restrict+
+      #   Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
       def add_foreign_key(from_table, to_table, options = {})
         return unless supports_foreign_keys?
 
-- 
cgit v1.2.3


From ad5c1a39346d559f26c11c2399117491a3d81c0b Mon Sep 17 00:00:00 2001
From: Robin Dupret <robin.dupret@gmail.com>
Date: Thu, 23 Jul 2015 14:27:09 +0200
Subject: Rename the enum_{prefix,suffix} options to _{prefix,suffix}

This makes it more clear that they are reserved keywords and also it
seems less redundant as the line already starts with the call to the
`enum` method.
---
 activerecord/lib/active_record/enum.rb | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb
index c0d9d9c1c8..9c9307df15 100644
--- a/activerecord/lib/active_record/enum.rb
+++ b/activerecord/lib/active_record/enum.rb
@@ -75,22 +75,22 @@ module ActiveRecord
   #
   #   Conversation.where("status <> ?", Conversation.statuses[:archived])
   #
-  # You can use the +:enum_prefix+ or +:enum_suffix+ options when you need
-  # to define multiple enums with same values. If the passed value is +true+,
-  # the methods are prefixed/suffixed with the name of the enum.
+  # You can use the +:_prefix+ or +:_suffix+ options when you need to define
+  # multiple enums with same values. If the passed value is +true+, the methods
+  # are prefixed/suffixed with the name of the enum.
   #
   #   class Invoice < ActiveRecord::Base
-  #     enum verification: [:done, :fail], enum_prefix: true
+  #     enum verification: [:done, :fail], _prefix: true
   #   end
   #
-  # It is also possible to supply a custom prefix.
+  # It is also possible to supply a custom value:
   #
   #   class Invoice < ActiveRecord::Base
-  #     enum verification: [:done, :fail], enum_prefix: :verification_status
+  #     enum verification: [:done, :fail], _prefix: :verification_status
   #   end
   #
-  # Note that <tt>:enum_prefix</tt>/<tt>:enum_suffix</tt> are reserved keywords
-  # and can not be used as an enum name.
+  # Note that <tt>:_prefix</tt>/<tt>:_suffix</tt> are reserved keywords and can
+  # not be used as enum names.
 
   module Enum
     def self.extended(base) # :nodoc:
@@ -137,8 +137,8 @@ module ActiveRecord
 
     def enum(definitions)
       klass = self
-      enum_prefix = definitions.delete(:enum_prefix)
-      enum_suffix = definitions.delete(:enum_suffix)
+      enum_prefix = definitions.delete(:_prefix)
+      enum_suffix = definitions.delete(:_suffix)
       definitions.each do |name, values|
         # statuses = { }
         enum_values = ActiveSupport::HashWithIndifferentAccess.new
-- 
cgit v1.2.3


From cdc32defcfc2ce5312c4b02e09f6cef2172843c6 Mon Sep 17 00:00:00 2001
From: Robin Dupret <robin.dupret@gmail.com>
Date: Thu, 23 Jul 2015 19:21:19 +0200
Subject: Improvements on the enum documentation [ci skip]

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]
---
 activerecord/lib/active_record/enum.rb | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb
index 9c9307df15..91a13cb0cd 100644
--- a/activerecord/lib/active_record/enum.rb
+++ b/activerecord/lib/active_record/enum.rb
@@ -77,20 +77,22 @@ module ActiveRecord
   #
   # You can use the +:_prefix+ or +:_suffix+ options when you need to define
   # multiple enums with same values. If the passed value is +true+, the methods
-  # are prefixed/suffixed with the name of the enum.
+  # are prefixed/suffixed with the name of the enum. It is also possible to
+  # supply a custom value:
   #
-  #   class Invoice < ActiveRecord::Base
-  #     enum verification: [:done, :fail], _prefix: true
+  #   class Conversation < ActiveRecord::Base
+  #     enum status: [:active, :archived], _suffix: true
+  #     enum comments_status: [:active, :inactive], _prefix: :comments
   #   end
   #
-  # It is also possible to supply a custom value:
+  # With the above example, the bang and predicate methods along with the
+  # associated scopes are now prefixed and/or suffixed accordingly:
   #
-  #   class Invoice < ActiveRecord::Base
-  #     enum verification: [:done, :fail], _prefix: :verification_status
-  #   end
+  #   conversation.active_status!
+  #   conversation.archived_status? # => false
   #
-  # Note that <tt>:_prefix</tt>/<tt>:_suffix</tt> are reserved keywords and can
-  # not be used as enum names.
+  #   conversation.comments_inactive!
+  #   conversation.comments_active? # => false
 
   module Enum
     def self.extended(base) # :nodoc:
-- 
cgit v1.2.3


From d937a1175f10586b892842348c1d6ecaa47aad2e Mon Sep 17 00:00:00 2001
From: Sean Griffin <sean@thoughtbot.com>
Date: Fri, 24 Jul 2015 09:13:20 -0600
Subject: `destroy` shouldn't raise when child associations fail to save

Deep down in the association internals, we're calling `destroy!` rather
than `destroy` when handling things like `dependent` or autosave
association callbacks. Unfortunately, due to the structure of the code
(e.g. it uses callbacks for everything), it's nearly impossible to pass
whether to call `destroy` or `destroy!` down to where we actually need
it.

As such, we have to do some legwork to handle this. Since the callbacks
are what actually raise the exception, we need to rescue it in
`ActiveRecord::Callbacks`, rather than `ActiveRecord::Persistence` where
it matters. (As an aside, if this code wasn't so callback heavy, it
would handling this would likely be as simple as changing `destroy` to
call `destroy!` instead of the other way around).

Since we don't want to lose the exception when `destroy!` is called (in
particular, we don't want the value of the `record` field to change to
the parent class), we have to do some additional legwork to hold onto it
where we can use it.

Again, all of this is ugly and there is definitely a better way to do
this. However, barring a much more significant re-architecting for what
I consider to be a reletively minor improvement, I'm willing to take
this small hit to the flow of this code (begrudgingly).
---
 activerecord/lib/active_record/callbacks.rb   | 3 +++
 activerecord/lib/active_record/persistence.rb | 9 ++++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb
index 19f0dca5a6..c7c769b283 100644
--- a/activerecord/lib/active_record/callbacks.rb
+++ b/activerecord/lib/active_record/callbacks.rb
@@ -290,6 +290,9 @@ module ActiveRecord
 
     def destroy #:nodoc:
       _run_destroy_callbacks { super }
+    rescue RecordNotDestroyed => e
+      @_association_destroy_exception = e
+      false
     end
 
     def touch(*) #:nodoc:
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 0a6e4ac0bd..09c36d7b4d 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -193,7 +193,7 @@ module ActiveRecord
     # and #destroy! raises ActiveRecord::RecordNotDestroyed.
     # See ActiveRecord::Callbacks for further details.
     def destroy!
-      destroy || raise(RecordNotDestroyed.new("Failed to destroy the record", self))
+      destroy || _raise_record_not_destroyed
     end
 
     # Returns an instance of the specified +klass+ with the attributes of the
@@ -548,5 +548,12 @@ module ActiveRecord
     def verify_readonly_attribute(name)
       raise ActiveRecordError, "#{name} is marked as readonly" if self.class.readonly_attributes.include?(name)
     end
+
+    def _raise_record_not_destroyed
+      @_association_destroy_exception ||= nil
+      raise @_association_destroy_exception || RecordNotDestroyed.new("Failed to destroy the record", self)
+    ensure
+      @_association_destroy_exception = nil
+    end
   end
 end
-- 
cgit v1.2.3


From 119b9181ece399c67213543fb5227b82688b536f Mon Sep 17 00:00:00 2001
From: Sean Griffin <sean@thoughtbot.com>
Date: Sat, 25 Jul 2015 13:05:05 -0600
Subject: Properly allow uniqueness validations on primary keys.

This is an alternate implementation of #20966.

[Sean Griffin & presskey]
---
 activerecord/lib/active_record/validations/uniqueness.rb | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 5106f4e127..32d17a1392 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -17,7 +17,9 @@ module ActiveRecord
         value = map_enum_attribute(finder_class, attribute, value)
 
         relation = build_relation(finder_class, table, attribute, value)
-        relation = relation.where.not(finder_class.primary_key => record.id) if record.persisted?
+        if record.persisted? && finder_class.primary_key.to_s != attribute.to_s
+          relation = relation.where.not(finder_class.primary_key => record.id)
+        end
         relation = scope_relation(record, table, relation)
         relation = relation.merge(options[:conditions]) if options[:conditions]
 
-- 
cgit v1.2.3


From a74fbb2972bb161c553d7a5bd3a13299de6c7927 Mon Sep 17 00:00:00 2001
From: Robin Dupret <robin.dupret@gmail.com>
Date: Tue, 28 Jul 2015 12:22:37 +0200
Subject: Add `:nodoc:` for internal testing methods [ci skip]

---
 activerecord/lib/active_record/fixtures.rb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index d062dd9e34..f1dc56df63 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -827,12 +827,12 @@ module ActiveRecord
   module TestFixtures
     extend ActiveSupport::Concern
 
-    def before_setup
+    def before_setup # :nodoc:
       setup_fixtures
       super
     end
 
-    def after_teardown
+    def after_teardown # :nodoc:
       super
       teardown_fixtures
     end
-- 
cgit v1.2.3


From f80aa5994603e684e3fecd3f53bfbf242c73a107 Mon Sep 17 00:00:00 2001
From: schneems <richard.schneeman@gmail.com>
Date: Fri, 24 Jul 2015 00:46:12 -0500
Subject: Decrease string allocations on AR#respond_to?

When a symbol is passed in, we call `to_s` on it which allocates a string. The two hardcoded symbols that are used internally are `:to_partial_path` and `:to_model`.

This change buys us 71,136 bytes of memory and 1,777 fewer objects per request.
---
 activerecord/lib/active_record/attribute_methods.rb | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index abe1d465a5..7fb899c242 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -230,7 +230,15 @@ module ActiveRecord
     #   person.respond_to(:nothing) # => false
     def respond_to?(name, include_private = false)
       return false unless super
-      name = name.to_s
+
+      case name
+      when :to_partial_path
+        name = "to_partial_path".freeze
+      when :to_model
+        name = "to_model".freeze
+      else
+        name = name.to_s
+      end
 
       # If the result is true then check for the select case.
       # For queries selecting a subset of columns, return false for unselected columns.
-- 
cgit v1.2.3


From 07f8a96aa14b642a8641dcb22dad07f995d3917e Mon Sep 17 00:00:00 2001
From: starbelly <starbelly@pobox.com>
Date: Sat, 1 Aug 2015 16:48:56 -0500
Subject:  Add run_cmd class method to ActiveRecord::Tasks::DatabaseTasks

  -   Added run_cmd() class method to dry up Kernel.system() messages within
      this namespace and avoid shell expansion by passing a list of
      arguments instead of a string

  -   Update structure_dump, structure_load, and related tests units to
      pass a list of params instead of using a string to
      avoid shell expansion
---
 .../lib/active_record/tasks/database_tasks.rb      | 13 ++++++++++++
 .../tasks/postgresql_database_tasks.rb             | 23 +++++++++++-----------
 2 files changed, 25 insertions(+), 11 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb
index 683741768b..94a8116b8b 100644
--- a/activerecord/lib/active_record/tasks/database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/database_tasks.rb
@@ -252,6 +252,19 @@ module ActiveRecord
         end
       end
 
+      def self.run_cmd(cmd, args, action)
+        fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
+      end
+
+      def run_cmd_error(cmd, args, action)
+        msg = "failed to execute:\n"
+        msg << "#{cmd} #{args.join(' ')}\n\n"
+        msg << "Please check that `#{cmd}` is :\n"
+        msg << " - present on this system\n"
+        msg << " - in your PATH\n"
+        msg << " - has proper permissions\n\n"
+      end
+
       private
 
       def class_for_adapter(adapter)
diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb
index d7da95c8a9..d406f24c31 100644
--- a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb
@@ -1,5 +1,3 @@
-require 'shellwords'
-
 module ActiveRecord
   module Tasks # :nodoc:
     class PostgreSQLDatabaseTasks # :nodoc:
@@ -55,19 +53,22 @@ module ActiveRecord
         when String
           ActiveRecord::Base.dump_schemas
         end
-        unless search_path.blank?
-          search_path = search_path.split(",").map{|search_path_part| "--schema=#{Shellwords.escape(search_path_part.strip)}" }.join(" ")
-        end
-
-        command = "pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(configuration['database'])}"
-        raise 'Error dumping database' unless Kernel.system(command)
 
+        args = ['-i', '-s', '-x', '-O', '-f', filename]
+        unless search_path.blank?
+          args << search_path.split(',').map do |part|
+            "--schema=#{part.strip}"
+          end.join(' ')
+        end 
+        args << configuration['database']
+        ActiveRecord::Tasks::DatabaseTasks.run_cmd('pg_dump', args, 'dumping')
         File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" }
       end
 
-      def structure_load(filename)
-        set_psql_env
-        Kernel.system("psql -X -q -f #{Shellwords.escape(filename)} #{configuration['database']}")
+      def structure_load(filename)      
+        set_psql_env 
+        args = [ '-q', '-f', filename, configuration['database'] ]
+        ActiveRecord::Tasks::DatabaseTasks.run_cmd('psql', args, 'loading' )
       end
 
       private
-- 
cgit v1.2.3


From 722abe1722a8bcf1798fc7f7f9a8cf4dcfa28e88 Mon Sep 17 00:00:00 2001
From: Sean Griffin <sean@thoughtbot.com>
Date: Sat, 1 Aug 2015 18:15:46 -0600
Subject: Fix test failures caused by #20884

PostgreSQL is strict about the usage of `DISTINCT` and `ORDER BY`, which
one of the tests demonstrated. The order clause is never going to be
relevant in the query we're performing, so let's just remove it
entirely.
---
 activerecord/lib/active_record/collection_cache_key.rb | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/collection_cache_key.rb b/activerecord/lib/active_record/collection_cache_key.rb
index 72b50c1d28..3c4ca3d116 100644
--- a/activerecord/lib/active_record/collection_cache_key.rb
+++ b/activerecord/lib/active_record/collection_cache_key.rb
@@ -12,7 +12,9 @@ module ActiveRecord
         column_type = type_for_attribute(timestamp_column.to_s)
         column = "#{connection.quote_table_name(collection.table_name)}.#{connection.quote_column_name(timestamp_column)}"
 
-        query = collection.select("COUNT(*) AS size", "MAX(#{column}) AS timestamp")
+        query = collection
+          .select("COUNT(*) AS size", "MAX(#{column}) AS timestamp")
+          .unscope(:order)
         result = connection.select_one(query)
 
         size = result["size"]
-- 
cgit v1.2.3


From f744d627364a9a98dedda5b30711bf80ebc3451f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mehmet=20Emin=20=C4=B0NA=C3=87?= <mehmetemininac@gmail.com>
Date: Sun, 2 Aug 2015 04:38:36 +0300
Subject: Use memoization for collection associations ids reader

Fixes #21082

remove extra space
---
 .../lib/active_record/associations/collection_association.rb        | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 87576abd92..0fc2b83b71 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -62,8 +62,10 @@ module ActiveRecord
             record.send(reflection.association_primary_key)
           end
         else
-          column  = "#{reflection.quoted_table_name}.#{reflection.association_primary_key}"
-          scope.pluck(column)
+          @association_ids ||= (
+            column = "#{reflection.quoted_table_name}.#{reflection.association_primary_key}"
+            scope.pluck(column)
+          )
         end
       end
 
-- 
cgit v1.2.3


From 977ffe880624bbd05f5ee1cc6e4fa51a999884ab Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Tue, 4 Aug 2015 04:59:50 +0900
Subject: Should use `server_info[:version]` instead of `info[:version]`

Because `info[:version]` is a client version, the server version is
`server_info[:version]`.
---
 activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index e97e82f056..b7db57c9fe 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -254,7 +254,7 @@ module ActiveRecord
       end
 
       def full_version
-        @full_version ||= @connection.info[:version]
+        @full_version ||= @connection.server_info[:version]
       end
 
       def set_field_encoding field_name
-- 
cgit v1.2.3


From 2bba65a2c6f5fdf5241b3be73f56a316fa823a61 Mon Sep 17 00:00:00 2001
From: Brendan Buckingham <brendan.buckingham@gmail.com>
Date: Thu, 6 Aug 2015 13:58:59 -0500
Subject: better docs for ActiveRecord::Migration#table_name_options

---
 activerecord/lib/active_record/migration.rb | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 4cfda302ea..b7b508d853 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -716,7 +716,9 @@ module ActiveRecord
       end
     end
 
-    def table_name_options(config = ActiveRecord::Base)
+    # Builds a hash for use in ActiveRecord::Migration#proper_table_name using
+    # the Active Record object's table_name prefix and suffix
+    def table_name_options(config = ActiveRecord::Base) #:nodoc:
       {
         table_name_prefix: config.table_name_prefix,
         table_name_suffix: config.table_name_suffix
-- 
cgit v1.2.3


From 25cee1f0373aa3b1d893413a959375480e0ac684 Mon Sep 17 00:00:00 2001
From: Sina Siadat <siadat@gmail.com>
Date: Sat, 18 Jul 2015 20:44:13 +0430
Subject: Add ActiveRecord::Relation#in_batches

`in_batches` yields Relation objects if a block is given, otherwise it
returns an instance of `BatchEnumerator`. The existing `find_each` and
`find_in_batches` methods work with batches of records. The new API
allows working with relation batches as well.

Examples:

    Person.in_batches.each_record(&:party_all_night!)
    Person.in_batches.update_all(awesome: true)
    Person.in_batches.delete_all
    Person.in_batches.map do |relation|
      relation.delete_all
      sleep 10 # Throttles the delete queries
    end
---
 activerecord/lib/active_record/querying.rb         |  2 +-
 activerecord/lib/active_record/relation.rb         |  7 ++
 activerecord/lib/active_record/relation/batches.rb | 98 ++++++++++++++++++++--
 .../relation/batches/batch_enumerator.rb           | 67 +++++++++++++++
 4 files changed, 164 insertions(+), 10 deletions(-)
 create mode 100644 activerecord/lib/active_record/relation/batches/batch_enumerator.rb

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb
index 4e597590e9..87a1988f2f 100644
--- a/activerecord/lib/active_record/querying.rb
+++ b/activerecord/lib/active_record/querying.rb
@@ -6,7 +6,7 @@ module ActiveRecord
     delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all
     delegate :find_by, :find_by!, to: :all
     delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, to: :all
-    delegate :find_each, :find_in_batches, to: :all
+    delegate :find_each, :find_in_batches, :in_batches, to: :all
     delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :or,
              :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly,
              :having, :create_with, :uniq, :distinct, :references, :none, :unscope, to: :all
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 3ed04dee3b..e47b7b1ed9 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -667,6 +667,13 @@ module ActiveRecord
       "#<#{self.class.name} [#{entries.join(', ')}]>"
     end
 
+    protected
+
+      def load_records(records)
+        @records = records
+        @loaded = true
+      end
+
     private
 
     def exec_queries
diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb
index e07580a563..beb8fa511c 100644
--- a/activerecord/lib/active_record/relation/batches.rb
+++ b/activerecord/lib/active_record/relation/batches.rb
@@ -1,3 +1,5 @@
+require "active_record/relation/batches/batch_enumerator"
+
 module ActiveRecord
   module Batches
     # Looping through a collection of records from the database
@@ -122,24 +124,102 @@ module ActiveRecord
         end
       end
 
+      in_batches(of: batch_size, begin_at: begin_at, end_at: end_at, load: true) do |batch|
+        yield batch.to_a
+      end
+    end
+
+    # Yields ActiveRecord::Relation objects to work with a batch of records.
+    #
+    #   Person.where("age > 21").in_batches do |relation|
+    #     relation.delete_all
+    #     sleep(10) # Throttle the delete queries
+    #   end
+    #
+    # If you do not provide a block to #in_batches, it will return a
+    # BatchEnumerator which is enumerable.
+    #
+    #   Person.in_batches.with_index do |relation, batch_index|
+    #     puts "Processing relation ##{batch_index}"
+    #     relation.each { |relation| relation.delete_all }
+    #   end
+    #
+    # Examples of calling methods on the returned BatchEnumerator object:
+    #
+    #   Person.in_batches.delete_all
+    #   Person.in_batches.update_all(awesome: true)
+    #   Person.in_batches.each_record(&:party_all_night!)
+    #
+    # ==== Options
+    # * <tt>:of</tt> - Specifies the size of the batch. Default to 1000.
+    # * <tt>:load</tt> - Specifies if the relation should be loaded. Default to false.
+    # * <tt>:begin_at</tt> - Specifies the primary key value to start from, inclusive of the value.
+    # * <tt>:end_at</tt> - Specifies the primary key value to end at, inclusive of the value.
+    #
+    # This is especially useful if you want to work with the
+    # ActiveRecord::Relation object instead of the array of records, or if
+    # you want multiple workers dealing with the same processing queue. You can
+    # make worker 1 handle all the records between id 0 and 10,000 and worker 2
+    # handle from 10,000 and beyond (by setting the +:begin_at+ and +:end_at+
+    # option on each worker).
+    #
+    #   # Let's process the next 2000 records
+    #   Person.in_batches(of: 2000, begin_at: 2000).update_all(awesome: true)
+    #
+    # An example of calling where query method on the relation:
+    #
+    #   Person.in_batches.each do |relation|
+    #     relation.update_all('age = age + 1')
+    #     relation.where('age > 21').update_all(should_party: true)
+    #     relation.where('age <= 21').delete_all
+    #   end
+    #
+    # NOTE: If you are going to iterate through each record, you should call
+    # #each_record on the yielded BatchEnumerator:
+    #
+    #   Person.in_batches.each_record(&:party_all_night!)
+    #
+    # NOTE: It's not possible to set the order. That is automatically set to
+    # ascending on the primary key ("id ASC") to make the batch ordering
+    # consistent. Therefore the primary key must be orderable, e.g an integer
+    # or a string.
+    #
+    # NOTE: You can't set the limit either, that's used to control the batch
+    # sizes.
+    def in_batches(of: 1000, begin_at: nil, end_at: nil, load: false)
+      relation = self
+      unless block_given?
+        return BatchEnumerator.new(of: of, begin_at: begin_at, end_at: end_at, relation: self)
+      end
+
       if logger && (arel.orders.present? || arel.taken.present?)
         logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size")
       end
 
-      relation = relation.reorder(batch_order).limit(batch_size)
+      relation = relation.reorder(batch_order).limit(of)
       relation = apply_limits(relation, begin_at, end_at)
-      records = relation.to_a
+      batch_relation = relation
+
+      loop do
+        if load
+          records = batch_relation.to_a
+          ids = records.map(&:id)
+          yielded_relation = self.where(primary_key => ids)
+          yielded_relation.load_records(records)
+        else
+          ids = batch_relation.pluck(primary_key)
+          yielded_relation = self.where(primary_key => ids)
+        end
 
-      while records.any?
-        records_size = records.size
-        primary_key_offset = records.last.id
-        raise "Primary key not included in the custom select clause" unless primary_key_offset
+        break if ids.empty?
 
-        yield records
+        primary_key_offset = ids.last
+        raise ArgumentError.new("Primary key not included in the custom select clause") unless primary_key_offset
 
-        break if records_size < batch_size
+        yield yielded_relation
 
-        records = relation.where(table[primary_key].gt(primary_key_offset)).to_a
+        break if ids.length < of
+        batch_relation = relation.where(table[primary_key].gt(primary_key_offset))
       end
     end
 
diff --git a/activerecord/lib/active_record/relation/batches/batch_enumerator.rb b/activerecord/lib/active_record/relation/batches/batch_enumerator.rb
new file mode 100644
index 0000000000..153aae9584
--- /dev/null
+++ b/activerecord/lib/active_record/relation/batches/batch_enumerator.rb
@@ -0,0 +1,67 @@
+module ActiveRecord
+  module Batches
+    class BatchEnumerator
+      include Enumerable
+
+      def initialize(of: 1000, begin_at: nil, end_at: nil, relation:) #:nodoc:
+        @of       = of
+        @relation = relation
+        @begin_at = begin_at
+        @end_at   = end_at
+      end
+
+      # Looping through a collection of records from the database (using the
+      # +all+ method, for example) is very inefficient since it will try to
+      # instantiate all the objects at once.
+      #
+      # In that case, batch processing methods allow you to work with the
+      # records in batches, thereby greatly reducing memory consumption.
+      #
+      #   Person.in_batches.each_record do |person|
+      #     person.do_awesome_stuff
+      #   end
+      #
+      #   Person.where("age > 21").in_batches(of: 10).each_record do |person|
+      #     person.party_all_night!
+      #   end
+      #
+      # If you do not provide a block to #each_record, it will return an Enumerator
+      # for chaining with other methods:
+      #
+      #   Person.in_batches.each_record.with_index do |person, index|
+      #     person.award_trophy(index + 1)
+      #   end
+      def each_record
+        return to_enum(:each_record) unless block_given?
+
+        @relation.to_enum(:in_batches, of: @of, begin_at: @begin_at, end_at: @end_at, load: true).each do |relation|
+          relation.to_a.each { |record| yield record }
+        end
+      end
+
+      # Delegates #delete_all, #update_all, #destroy_all methods to each batch.
+      #
+      #   People.in_batches.delete_all
+      #   People.in_batches.destroy_all('age < 10')
+      #   People.in_batches.update_all('age = age + 1')
+      [:delete_all, :update_all, :destroy_all].each do |method|
+        define_method(method) do |*args, &block|
+          @relation.to_enum(:in_batches, of: @of, begin_at: @begin_at, end_at: @end_at, load: false).each do |relation|
+            relation.send(method, *args, &block)
+          end
+        end
+      end
+
+      # Yields an ActiveRecord::Relation object for each batch of records.
+      #
+      #   Person.in_batches.each do |relation|
+      #     relation.update_all(awesome: true)
+      #   end
+      def each
+        enum = @relation.to_enum(:in_batches, of: @of, begin_at: @begin_at, end_at: @end_at, load: false)
+        return enum.each { |relation| yield relation } if block_given?
+        enum
+      end
+    end
+  end
+end
-- 
cgit v1.2.3


From f7ebdb1ac51f26cff76e5642a75717df1b446746 Mon Sep 17 00:00:00 2001
From: Zachary Scott <e@zzak.io>
Date: Tue, 5 May 2015 11:11:35 -0700
Subject: Remove XML Serialization from core.

This includes the following classes:

- ActiveModel::Serializers::Xml
- ActiveRecord::Serialization::XmlSerializer
---
 activerecord/lib/active_record/serialization.rb    |   2 -
 .../active_record/serializers/xml_serializer.rb    | 193 ---------------------
 2 files changed, 195 deletions(-)
 delete mode 100644 activerecord/lib/active_record/serializers/xml_serializer.rb

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb
index 48c12dcf9f..23dc6465af 100644
--- a/activerecord/lib/active_record/serialization.rb
+++ b/activerecord/lib/active_record/serialization.rb
@@ -18,5 +18,3 @@ module ActiveRecord #:nodoc:
     end
   end
 end
-
-require 'active_record/serializers/xml_serializer'
diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb
deleted file mode 100644
index 89b7e0be82..0000000000
--- a/activerecord/lib/active_record/serializers/xml_serializer.rb
+++ /dev/null
@@ -1,193 +0,0 @@
-require 'active_support/core_ext/hash/conversions'
-
-module ActiveRecord #:nodoc:
-  module Serialization
-    include ActiveModel::Serializers::Xml
-
-    # Builds an XML document to represent the model. Some configuration is
-    # available through +options+. However more complicated cases should
-    # override ActiveRecord::Base#to_xml.
-    #
-    # By default the generated XML document will include the processing
-    # instruction and all the object's attributes. For example:
-    #
-    #   <?xml version="1.0" encoding="UTF-8"?>
-    #   <topic>
-    #     <title>The First Topic</title>
-    #     <author-name>David</author-name>
-    #     <id type="integer">1</id>
-    #     <approved type="boolean">false</approved>
-    #     <replies-count type="integer">0</replies-count>
-    #     <bonus-time type="dateTime">2000-01-01T08:28:00+12:00</bonus-time>
-    #     <written-on type="dateTime">2003-07-16T09:28:00+1200</written-on>
-    #     <content>Have a nice day</content>
-    #     <author-email-address>david@loudthinking.com</author-email-address>
-    #     <parent-id></parent-id>
-    #     <last-read type="date">2004-04-15</last-read>
-    #   </topic>
-    #
-    # This behavior can be controlled with <tt>:only</tt>, <tt>:except</tt>,
-    # <tt>:skip_instruct</tt>, <tt>:skip_types</tt>, <tt>:dasherize</tt> and <tt>:camelize</tt> .
-    # The <tt>:only</tt> and <tt>:except</tt> options are the same as for the
-    # +attributes+ method. The default is to dasherize all column names, but you
-    # can disable this setting <tt>:dasherize</tt> to +false+. Setting <tt>:camelize</tt>
-    # to +true+ will camelize all column names - this also overrides <tt>:dasherize</tt>.
-    # To not have the column type included in the XML output set <tt>:skip_types</tt> to +true+.
-    #
-    # For instance:
-    #
-    #   topic.to_xml(skip_instruct: true, except: [ :id, :bonus_time, :written_on, :replies_count ])
-    #
-    #   <topic>
-    #     <title>The First Topic</title>
-    #     <author-name>David</author-name>
-    #     <approved type="boolean">false</approved>
-    #     <content>Have a nice day</content>
-    #     <author-email-address>david@loudthinking.com</author-email-address>
-    #     <parent-id></parent-id>
-    #     <last-read type="date">2004-04-15</last-read>
-    #   </topic>
-    #
-    # To include first level associations use <tt>:include</tt>:
-    #
-    #   firm.to_xml include: [ :account, :clients ]
-    #
-    #   <?xml version="1.0" encoding="UTF-8"?>
-    #   <firm>
-    #     <id type="integer">1</id>
-    #     <rating type="integer">1</rating>
-    #     <name>37signals</name>
-    #     <clients type="array">
-    #       <client>
-    #         <rating type="integer">1</rating>
-    #         <name>Summit</name>
-    #       </client>
-    #       <client>
-    #         <rating type="integer">1</rating>
-    #         <name>Microsoft</name>
-    #       </client>
-    #     </clients>
-    #     <account>
-    #       <id type="integer">1</id>
-    #       <credit-limit type="integer">50</credit-limit>
-    #     </account>
-    #   </firm>
-    #
-    # Additionally, the record being serialized will be passed to a Proc's second
-    # parameter. This allows for ad hoc additions to the resultant document that
-    # incorporate the context of the record being serialized. And by leveraging the
-    # closure created by a Proc, to_xml can be used to add elements that normally fall
-    # outside of the scope of the model -- for example, generating and appending URLs
-    # associated with models.
-    #
-    #   proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
-    #   firm.to_xml procs: [ proc ]
-    #
-    #   <firm>
-    #     # ... normal attributes as shown above ...
-    #     <name-reverse>slangis73</name-reverse>
-    #   </firm>
-    #
-    # To include deeper levels of associations pass a hash like this:
-    #
-    #   firm.to_xml include: {account: {}, clients: {include: :address}}
-    #   <?xml version="1.0" encoding="UTF-8"?>
-    #   <firm>
-    #     <id type="integer">1</id>
-    #     <rating type="integer">1</rating>
-    #     <name>37signals</name>
-    #     <clients type="array">
-    #       <client>
-    #         <rating type="integer">1</rating>
-    #         <name>Summit</name>
-    #         <address>
-    #           ...
-    #         </address>
-    #       </client>
-    #       <client>
-    #         <rating type="integer">1</rating>
-    #         <name>Microsoft</name>
-    #         <address>
-    #           ...
-    #         </address>
-    #       </client>
-    #     </clients>
-    #     <account>
-    #       <id type="integer">1</id>
-    #       <credit-limit type="integer">50</credit-limit>
-    #     </account>
-    #   </firm>
-    #
-    # To include any methods on the model being called use <tt>:methods</tt>:
-    #
-    #   firm.to_xml methods: [ :calculated_earnings, :real_earnings ]
-    #
-    #   <firm>
-    #     # ... normal attributes as shown above ...
-    #     <calculated-earnings>100000000000000000</calculated-earnings>
-    #     <real-earnings>5</real-earnings>
-    #   </firm>
-    #
-    # To call any additional Procs use <tt>:procs</tt>. The Procs are passed a
-    # modified version of the options hash that was given to +to_xml+:
-    #
-    #   proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
-    #   firm.to_xml procs: [ proc ]
-    #
-    #   <firm>
-    #     # ... normal attributes as shown above ...
-    #     <abc>def</abc>
-    #   </firm>
-    #
-    # Alternatively, you can yield the builder object as part of the +to_xml+ call:
-    #
-    #   firm.to_xml do |xml|
-    #     xml.creator do
-    #       xml.first_name "David"
-    #       xml.last_name "Heinemeier Hansson"
-    #     end
-    #   end
-    #
-    #   <firm>
-    #     # ... normal attributes as shown above ...
-    #     <creator>
-    #       <first_name>David</first_name>
-    #       <last_name>Heinemeier Hansson</last_name>
-    #     </creator>
-    #   </firm>
-    #
-    # As noted above, you may override +to_xml+ in your ActiveRecord::Base
-    # subclasses to have complete control about what's generated. The general
-    # form of doing this is:
-    #
-    #   class IHaveMyOwnXML < ActiveRecord::Base
-    #     def to_xml(options = {})
-    #       require 'builder'
-    #       options[:indent] ||= 2
-    #       xml = options[:builder] ||= ::Builder::XmlMarkup.new(indent: options[:indent])
-    #       xml.instruct! unless options[:skip_instruct]
-    #       xml.level_one do
-    #         xml.tag!(:second_level, 'content')
-    #       end
-    #     end
-    #   end
-    def to_xml(options = {}, &block)
-      XmlSerializer.new(self, options).serialize(&block)
-    end
-  end
-
-  class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc:
-    class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc:
-      def compute_type
-        klass = @serializable.class
-        cast_type = klass.type_for_attribute(name)
-
-        type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name] || cast_type.type
-
-        { :text => :string,
-          :time => :datetime }[type] || type
-      end
-      protected :compute_type
-    end
-  end
-end
-- 
cgit v1.2.3


From 5ec9e9349e320e5547c8b36266dbeed07082dd51 Mon Sep 17 00:00:00 2001
From: Matt Hanlon <hanlon@skytap.com>
Date: Fri, 7 Aug 2015 12:33:09 -0700
Subject: use correct DB connection for generated HABTM table

---
 .../associations/builder/has_and_belongs_to_many.rb            | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
index ffd9c9d6fc..b18d99d54e 100644
--- a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
+++ b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
@@ -46,7 +46,7 @@ module ActiveRecord::Associations::Builder
 
       join_model = Class.new(ActiveRecord::Base) {
         class << self;
-          attr_accessor :class_resolver
+          attr_accessor :left_model
           attr_accessor :name
           attr_accessor :table_name_resolver
           attr_accessor :left_reflection
@@ -58,7 +58,7 @@ module ActiveRecord::Associations::Builder
         end
 
         def self.compute_type(class_name)
-          class_resolver.compute_type class_name
+          left_model.compute_type class_name
         end
 
         def self.add_left_association(name, options)
@@ -72,11 +72,15 @@ module ActiveRecord::Associations::Builder
           self.right_reflection = _reflect_on_association(rhs_name)
         end
 
+        def self.retrieve_connection
+          left_model.retrieve_connection
+        end
+
       }
 
       join_model.name                = "HABTM_#{association_name.to_s.camelize}"
       join_model.table_name_resolver = habtm
-      join_model.class_resolver      = lhs_model
+      join_model.left_model          = lhs_model
 
       join_model.add_left_association :left_side, anonymous_class: lhs_model
       join_model.add_right_association association_name, belongs_to_options(options)
-- 
cgit v1.2.3


From 468cdfcc8516bf9f0d990bcf11b785875c57b286 Mon Sep 17 00:00:00 2001
From: Miles Starkenburg <miles@substantial.com>
Date: Sat, 8 Aug 2015 13:15:28 -0700
Subject: Reference actual classes

---
 activerecord/lib/active_record/railtie.rb | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index da6b8447d3..459d6256fa 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -16,11 +16,11 @@ module ActiveRecord
     config.app_generators.orm :active_record, :migration => true,
                                               :timestamps => true
 
-    config.app_middleware.insert_after "::ActionDispatch::Callbacks",
-      "ActiveRecord::QueryCache"
+    config.app_middleware.insert_after ::ActionDispatch::Callbacks,
+      ActiveRecord::QueryCache
 
-    config.app_middleware.insert_after "::ActionDispatch::Callbacks",
-      "ActiveRecord::ConnectionAdapters::ConnectionManagement"
+    config.app_middleware.insert_after ::ActionDispatch::Callbacks,
+      ActiveRecord::ConnectionAdapters::ConnectionManagement
 
     config.action_dispatch.rescue_responses.merge!(
       'ActiveRecord::RecordNotFound'   => :not_found,
@@ -78,7 +78,7 @@ module ActiveRecord
 
     initializer "active_record.migration_error" do
       if config.active_record.delete(:migration_error) == :page_load
-        config.app_middleware.insert_after "::ActionDispatch::Callbacks",
+        config.app_middleware.insert_after ::ActionDispatch::Callbacks,
           "ActiveRecord::Migration::CheckPending"
       end
     end
-- 
cgit v1.2.3


From ddbd6e7e44e5183ae64ca8749dcf720e843d2355 Mon Sep 17 00:00:00 2001
From: akihiro17 <coolwizard11@gmail.com>
Date: Wed, 12 Aug 2015 11:33:02 +0900
Subject: [ci skip] Fix the indentation

---
 .../lib/active_record/attribute_methods.rb         | 26 +++++++++++-----------
 1 file changed, 13 insertions(+), 13 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 7fb899c242..0862306749 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -385,27 +385,27 @@ module ActiveRecord
     #
     # For example:
     #
-    # class PostsController < ActionController::Base
-    #   after_action :print_accessed_fields, only: :index
+    #   class PostsController < ActionController::Base
+    #     after_action :print_accessed_fields, only: :index
     #
-    #   def index
-    #     @posts = Post.all
-    #   end
+    #     def index
+    #       @posts = Post.all
+    #     end
     #
-    #   private
+    #     private
     #
-    #   def print_accessed_fields
-    #     p @posts.first.accessed_fields
+    #     def print_accessed_fields
+    #       p @posts.first.accessed_fields
+    #     end
     #   end
-    # end
     #
     # Which allows you to quickly change your code to:
     #
-    # class PostsController < ActionController::Base
-    #   def index
-    #     @posts = Post.select(:id, :title, :author_id, :updated_at)
+    #   class PostsController < ActionController::Base
+    #     def index
+    #       @posts = Post.select(:id, :title, :author_id, :updated_at)
+    #     end
     #   end
-    # end
     def accessed_fields
       @attributes.accessed
     end
-- 
cgit v1.2.3


From 60f7e0ca11d7fd33756ad36881eb947e0eb4d149 Mon Sep 17 00:00:00 2001
From: Yves Senn <yves.senn@gmail.com>
Date: Wed, 12 Aug 2015 16:17:04 +0200
Subject: docs, tiny rdoc markup fix. [ci skip]

`+` doesn't work around content with spaces fallback `<tt>`.
---
 activerecord/lib/active_record/callbacks.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb
index c7c769b283..ccdbebbc77 100644
--- a/activerecord/lib/active_record/callbacks.rb
+++ b/activerecord/lib/active_record/callbacks.rb
@@ -206,7 +206,8 @@ module ActiveRecord
   # == Ordering callbacks
   #
   # Sometimes the code needs that the callbacks execute in a specific order. For example, a +before_destroy+
-  # callback (+log_children+ in this case) should be executed before the children get destroyed by the +dependent: destroy+ option.
+  # callback (+log_children+ in this case) should be executed before the children get destroyed by the
+  # <tt>dependent: destroy</tt> option.
   #
   # Let's look at the code below:
   #
-- 
cgit v1.2.3


From 93dc0b43d1fae1aa34032f9cab8f0822ea33b54d Mon Sep 17 00:00:00 2001
From: akihiro17 <coolwizard11@gmail.com>
Date: Wed, 12 Aug 2015 23:53:10 +0900
Subject: [ci skip] Fix rdoc markup

---
 activerecord/lib/active_record/attribute_methods/serialization.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index e03bf5945d..60eecab0d0 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -11,7 +11,7 @@ module ActiveRecord
         # serialized object must be of that class on assignment and retrieval.
         # Otherwise <tt>SerializationTypeMismatch</tt> will be raised.
         #
-        # Empty objects as +{}+, in the case of +Hash+, or +[]+, in the case of
+        # Empty objects as <tt>{}</tt>, in the case of +Hash+, or <tt>[]</tt>, in the case of
         # +Array+, will always be persisted as null.
         #
         # Keep in mind that database adapters handle certain serialization tasks
-- 
cgit v1.2.3


From dc3230b156a4cfe5a8fbe3636edf0117f8e122cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?=
 <rafaelmfranca@gmail.com>
Date: Wed, 12 Aug 2015 21:14:42 -0300
Subject: Skip statement cache on through association reader

If the through class has default scopes we should skip the statement
cache.

Closes #20745.
---
 activerecord/lib/active_record/associations/association.rb        | 8 ++++++++
 .../lib/active_record/associations/collection_association.rb      | 7 +------
 .../lib/active_record/associations/singular_association.rb        | 7 +------
 3 files changed, 10 insertions(+), 12 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb
index 7c729676a7..c7b396f3d4 100644
--- a/activerecord/lib/active_record/associations/association.rb
+++ b/activerecord/lib/active_record/associations/association.rb
@@ -251,6 +251,14 @@ module ActiveRecord
             initialize_attributes(record)
           end
         end
+
+        # Returns true if statement cache should be skipped on the association reader.
+        def skip_statement_cache?
+          reflection.scope_chain.any?(&:any?) ||
+            scope.eager_loading? ||
+            klass.scope_attributes? ||
+            reflection.source_reflection.active_record.default_scopes.any?
+        end
     end
   end
 end
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 0fc2b83b71..256df3ca11 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -442,12 +442,7 @@ module ActiveRecord
 
       private
       def get_records
-        if reflection.scope_chain.any?(&:any?) ||
-          scope.eager_loading? ||
-          klass.scope_attributes?
-
-          return scope.to_a
-        end
+        return scope.to_a if skip_statement_cache?
 
         conn = klass.connection
         sc = reflection.association_scope_cache(conn, owner) do
diff --git a/activerecord/lib/active_record/associations/singular_association.rb b/activerecord/lib/active_record/associations/singular_association.rb
index 30c5d72482..03cb8cb8c3 100644
--- a/activerecord/lib/active_record/associations/singular_association.rb
+++ b/activerecord/lib/active_record/associations/singular_association.rb
@@ -47,12 +47,7 @@ module ActiveRecord
         end
 
         def get_records
-          if reflection.scope_chain.any?(&:any?) ||
-              scope.eager_loading? ||
-              klass.scope_attributes?
-
-            return scope.limit(1).to_a
-          end
+          return scope.limit(1).to_a if skip_statement_cache?
 
           conn = klass.connection
           sc = reflection.association_scope_cache(conn, owner) do
-- 
cgit v1.2.3


From e50fe85180648be0c4216bd0111f05be1df0988a Mon Sep 17 00:00:00 2001
From: Yves Senn <yves.senn@gmail.com>
Date: Thu, 13 Aug 2015 16:35:09 +0200
Subject: descriptive error message when fixtures contian a missing column.

Closes #21201.
---
 .../connection_adapters/abstract/database_statements.rb           | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 38dd9578fe..1e13b24867 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -289,8 +289,12 @@ module ActiveRecord
         columns = schema_cache.columns_hash(table_name)
 
         binds = fixture.map do |name, value|
-          type = lookup_cast_type_from_column(columns[name])
-          Relation::QueryAttribute.new(name, value, type)
+          if column = columns[name]
+            type = lookup_cast_type_from_column(column)
+            Relation::QueryAttribute.new(name, value, type)
+          else
+            raise Fixture::FixtureError, %(table "#{table_name}" has no column named "#{name}".)
+          end
         end
         key_list = fixture.keys.map { |name| quote_column_name(name) }
         value_list = prepare_binds_for_database(binds).map do |value|
-- 
cgit v1.2.3


From cdbed54fa999aacf388899b761de84d91fdb5a7e Mon Sep 17 00:00:00 2001
From: Jon Atack <jonnyatack@gmail.com>
Date: Fri, 14 Aug 2015 14:58:56 +0200
Subject: Fix middleware deprecation message. Related to #21172.

---
 activerecord/lib/active_record/railtie.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index 459d6256fa..6dd54f9262 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -79,7 +79,7 @@ module ActiveRecord
     initializer "active_record.migration_error" do
       if config.active_record.delete(:migration_error) == :page_load
         config.app_middleware.insert_after ::ActionDispatch::Callbacks,
-          "ActiveRecord::Migration::CheckPending"
+          ActiveRecord::Migration::CheckPending
       end
     end
 
-- 
cgit v1.2.3


From 8bd064ec2b9f51461aa5407b8b171d0ba22d48ff Mon Sep 17 00:00:00 2001
From: ravindra kumar kumawat <ravikumawat87@gmail.com>
Date: Tue, 18 Aug 2015 11:13:15 +0530
Subject: Add Docs for ActiveRecord #check_pending [ci skip]

---
 activerecord/lib/active_record/migration.rb | 1 +
 1 file changed, 1 insertion(+)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 192a456846..5af788bc10 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -373,6 +373,7 @@ module ActiveRecord
       attr_accessor :delegate # :nodoc:
       attr_accessor :disable_ddl_transaction # :nodoc:
 
+      # Raises <tt>ActiveRecord::PendingMigrationError</tt> error if any migrations are pending.
       def check_pending!(connection = Base.connection)
         raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator.needs_migration?(connection)
       end
-- 
cgit v1.2.3


From 820726704d2b2b4ba040b7ab54f9f626b622247e Mon Sep 17 00:00:00 2001
From: prakash <prakash@punchh.com>
Date: Tue, 18 Aug 2015 11:39:52 +0530
Subject: Correct error message in Standard American english and add a test
 case for the same.

---
 activerecord/lib/active_record/associations/preloader.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/preloader.rb b/activerecord/lib/active_record/associations/preloader.rb
index 6ecc741195..3992a240b9 100644
--- a/activerecord/lib/active_record/associations/preloader.rb
+++ b/activerecord/lib/active_record/associations/preloader.rb
@@ -116,7 +116,7 @@ module ActiveRecord
         when String
           preloaders_for_one(association.to_sym, records, scope)
         else
-          raise ArgumentError, "#{association.inspect} was not recognised for preload"
+          raise ArgumentError, "#{association.inspect} was not recognized for preload"
         end
       end
 
-- 
cgit v1.2.3


From 89d5d1cafb23280bda3f303442387e71353c9e49 Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Tue, 4 Aug 2015 04:16:54 +0900
Subject: Add a native JSON data type support in MySQL

As of MySQL 5.7.8, MySQL supports a native JSON data type.

Example:

    create_table :json_data_type do |t|
      t.json :settings
    end
---
 .../connection_adapters/abstract_adapter.rb        |  5 +++
 .../connection_adapters/abstract_mysql_adapter.rb  | 39 ++++++++++++++++------
 .../connection_adapters/mysql2_adapter.rb          |  4 +++
 .../connection_adapters/postgresql/oid.rb          |  1 -
 .../connection_adapters/postgresql/oid/json.rb     | 35 -------------------
 .../connection_adapters/postgresql/oid/jsonb.rb    |  2 +-
 .../connection_adapters/postgresql_adapter.rb      |  7 ++--
 activerecord/lib/active_record/type.rb             |  2 ++
 activerecord/lib/active_record/type/json.rb        | 31 +++++++++++++++++
 9 files changed, 76 insertions(+), 50 deletions(-)
 delete mode 100644 activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb
 create mode 100644 activerecord/lib/active_record/type/json.rb

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 56227ddd80..ed14c781c6 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -266,6 +266,11 @@ module ActiveRecord
         false
       end
 
+      # Does this adapter support json data type?
+      def supports_json?
+        false
+      end
+
       # This is meant to be implemented by the adapters that support extensions
       def disable_extension(name)
       end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index af156c9c78..96ea866580 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -10,6 +10,10 @@ module ActiveRecord
           options[:auto_increment] = true if type == :bigint
           super
         end
+
+        def json(*args, **options)
+          args.each { |name| column(name, :json, options) }
+        end
       end
 
       class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
@@ -242,17 +246,19 @@ module ActiveRecord
       QUOTED_TRUE, QUOTED_FALSE = '1', '0'
 
       NATIVE_DATABASE_TYPES = {
-        :primary_key => "int(11) auto_increment PRIMARY KEY",
-        :string      => { :name => "varchar", :limit => 255 },
-        :text        => { :name => "text" },
-        :integer     => { :name => "int", :limit => 4 },
-        :float       => { :name => "float" },
-        :decimal     => { :name => "decimal" },
-        :datetime    => { :name => "datetime" },
-        :time        => { :name => "time" },
-        :date        => { :name => "date" },
-        :binary      => { :name => "blob" },
-        :boolean     => { :name => "tinyint", :limit => 1 }
+        primary_key: "int(11) auto_increment PRIMARY KEY",
+        string:      { name: "varchar", limit: 255 },
+        text:        { name: "text" },
+        integer:     { name: "int", limit: 4 },
+        float:       { name: "float" },
+        decimal:     { name: "decimal" },
+        datetime:    { name: "datetime" },
+        time:        { name: "time" },
+        date:        { name: "date" },
+        binary:      { name: "blob" },
+        boolean:     { name: "tinyint", limit: 1 },
+        bigint:      { name: "bigint" },
+        json:        { name: "json" },
       }
 
       INDEX_TYPES  = [:fulltext, :spatial]
@@ -790,6 +796,7 @@ module ActiveRecord
         m.register_type %r(longblob)i,   Type::Binary.new(limit: 2**32 - 1)
         m.register_type %r(^float)i,     Type::Float.new(limit: 24)
         m.register_type %r(^double)i,    Type::Float.new(limit: 53)
+        m.register_type %r(^json)i,      MysqlJson.new
 
         register_integer_type m, %r(^bigint)i,    limit: 8
         register_integer_type m, %r(^int)i,       limit: 4
@@ -1043,6 +1050,14 @@ module ActiveRecord
         end
       end
 
+      class MysqlJson < Type::Json # :nodoc:
+        def changed_in_place?(raw_old_value, new_value)
+          # Normalization is required because MySQL JSON data format includes
+          # the space between the elements.
+          super(serialize(deserialize(raw_old_value)), new_value)
+        end
+      end
+
       class MysqlString < Type::String # :nodoc:
         def serialize(value)
           case value
@@ -1063,6 +1078,8 @@ module ActiveRecord
         end
       end
 
+      ActiveRecord::Type.register(:json, MysqlJson, adapter: :mysql)
+      ActiveRecord::Type.register(:json, MysqlJson, adapter: :mysql2)
       ActiveRecord::Type.register(:string, MysqlString, adapter: :mysql)
       ActiveRecord::Type.register(:string, MysqlString, adapter: :mysql2)
     end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index b7db57c9fe..ff43c7ec42 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -41,6 +41,10 @@ module ActiveRecord
         true
       end
 
+      def supports_json?
+        version >= '5.7.8'
+      end
+
       # HELPER METHODS ===========================================
 
       def each_hash(result) # :nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index 68752cdd80..37226831dc 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -8,7 +8,6 @@ require 'active_record/connection_adapters/postgresql/oid/decimal'
 require 'active_record/connection_adapters/postgresql/oid/enum'
 require 'active_record/connection_adapters/postgresql/oid/hstore'
 require 'active_record/connection_adapters/postgresql/oid/inet'
-require 'active_record/connection_adapters/postgresql/oid/json'
 require 'active_record/connection_adapters/postgresql/oid/jsonb'
 require 'active_record/connection_adapters/postgresql/oid/money'
 require 'active_record/connection_adapters/postgresql/oid/point'
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb
deleted file mode 100644
index 8e1256baad..0000000000
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-module ActiveRecord
-  module ConnectionAdapters
-    module PostgreSQL
-      module OID # :nodoc:
-        class Json < Type::Value # :nodoc:
-          include Type::Helpers::Mutable
-
-          def type
-            :json
-          end
-
-          def deserialize(value)
-            if value.is_a?(::String)
-              ::ActiveSupport::JSON.decode(value) rescue nil
-            else
-              value
-            end
-          end
-
-          def serialize(value)
-            if value.is_a?(::Array) || value.is_a?(::Hash)
-              ::ActiveSupport::JSON.encode(value)
-            else
-              value
-            end
-          end
-
-          def accessor
-            ActiveRecord::Store::StringKeyedHashAccessor
-          end
-        end
-      end
-    end
-  end
-end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
index 87391b5dc7..1f6d63582c 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
@@ -2,7 +2,7 @@ module ActiveRecord
   module ConnectionAdapters
     module PostgreSQL
       module OID # :nodoc:
-        class Jsonb < Json # :nodoc:
+        class Jsonb < Type::Json # :nodoc:
           def type
             :jsonb
           end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 2c43c46a3d..861edbf3a2 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -201,6 +201,10 @@ module ActiveRecord
         true
       end
 
+      def supports_json?
+        postgresql_version >= 90200
+      end
+
       def index_algorithms
         { concurrently: 'CONCURRENTLY' }
       end
@@ -478,7 +482,7 @@ module ActiveRecord
           m.register_type 'bytea', OID::Bytea.new
           m.register_type 'point', OID::Point.new
           m.register_type 'hstore', OID::Hstore.new
-          m.register_type 'json', OID::Json.new
+          m.register_type 'json', Type::Json.new
           m.register_type 'jsonb', OID::Jsonb.new
           m.register_type 'cidr', OID::Cidr.new
           m.register_type 'inet', OID::Inet.new
@@ -834,7 +838,6 @@ module ActiveRecord
         ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
         ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
         ActiveRecord::Type.register(:inet, OID::Inet, adapter: :postgresql)
-        ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
         ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
         ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
         ActiveRecord::Type.register(:point, OID::Point, adapter: :postgresql)
diff --git a/activerecord/lib/active_record/type.rb b/activerecord/lib/active_record/type.rb
index 2c0cda69d0..8f56a37f3c 100644
--- a/activerecord/lib/active_record/type.rb
+++ b/activerecord/lib/active_record/type.rb
@@ -10,6 +10,7 @@ require 'active_record/type/decimal'
 require 'active_record/type/decimal_without_scale'
 require 'active_record/type/float'
 require 'active_record/type/integer'
+require 'active_record/type/json'
 require 'active_record/type/serialized'
 require 'active_record/type/string'
 require 'active_record/type/text'
@@ -59,6 +60,7 @@ module ActiveRecord
     register(:decimal, Type::Decimal, override: false)
     register(:float, Type::Float, override: false)
     register(:integer, Type::Integer, override: false)
+    register(:json, Type::Json, override: false)
     register(:string, Type::String, override: false)
     register(:text, Type::Text, override: false)
     register(:time, Type::Time, override: false)
diff --git a/activerecord/lib/active_record/type/json.rb b/activerecord/lib/active_record/type/json.rb
new file mode 100644
index 0000000000..1728bd3a8e
--- /dev/null
+++ b/activerecord/lib/active_record/type/json.rb
@@ -0,0 +1,31 @@
+module ActiveRecord
+  module Type
+    class Json < Type::Value # :nodoc:
+      include Type::Helpers::Mutable
+
+      def type
+        :json
+      end
+
+      def deserialize(value)
+        if value.is_a?(::String)
+          ::ActiveSupport::JSON.decode(value) rescue nil
+        else
+          value
+        end
+      end
+
+      def serialize(value)
+        if value.is_a?(::Array) || value.is_a?(::Hash)
+          ::ActiveSupport::JSON.encode(value)
+        else
+          value
+        end
+      end
+
+      def accessor
+        ActiveRecord::Store::StringKeyedHashAccessor
+      end
+    end
+  end
+end
-- 
cgit v1.2.3


From c351a823adf7b92e8439bf68c043019b95733d18 Mon Sep 17 00:00:00 2001
From: sjain1107 <sakshijain1107@gmail.com>
Date: Tue, 18 Aug 2015 10:37:44 +0530
Subject: Added docs for TableDefinition #coloumns & #remove_column [ci skip]

---
 .../active_record/connection_adapters/abstract/schema_definitions.rb   | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index d17e272ed1..1658317408 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -214,6 +214,7 @@ module ActiveRecord
         @name = name
       end
 
+      # Returns an array of ColumnDefinitions for the columns of the table.
       def columns; @columns_hash.values; end
 
       # Returns a ColumnDefinition for the column with name +name+.
@@ -369,6 +370,8 @@ module ActiveRecord
         self
       end
 
+      # remove the column +name+ from the table.
+      #   remove_column(:account_id)
       def remove_column(name)
         @columns_hash.delete name.to_s
       end
-- 
cgit v1.2.3


From 50e4afff209ee6dcb50938b59bff32255a3f543e Mon Sep 17 00:00:00 2001
From: Yves Senn <yves.senn@gmail.com>
Date: Thu, 20 Aug 2015 12:07:02 +0200
Subject: uniqueness validation raises error for persisted record without pk.

Closes #21304.

While we can validate uniqueness for record without primary key on
creation, there is no way to exclude the current record when
updating. (The update itself will need a primary key to work correctly).
---
 activerecord/lib/active_record/errors.rb                 | 7 ++++---
 activerecord/lib/active_record/validations/uniqueness.rb | 6 +++++-
 2 files changed, 9 insertions(+), 4 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb
index d589620f8a..718f04871d 100644
--- a/activerecord/lib/active_record/errors.rb
+++ b/activerecord/lib/active_record/errors.rb
@@ -218,11 +218,12 @@ module ActiveRecord
   class UnknownPrimaryKey < ActiveRecordError
     attr_reader :model
 
-    def initialize(model)
-      super("Unknown primary key for table #{model.table_name} in model #{model}.")
+    def initialize(model, description = nil)
+      message = "Unknown primary key for table #{model.table_name} in model #{model}."
+      message += "\n#{description}" if description
+      super(message)
       @model = model
     end
-
   end
 
   # Raised when a relation cannot be mutated because it's already loaded.
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 32d17a1392..5706bbd903 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -18,7 +18,11 @@ module ActiveRecord
 
         relation = build_relation(finder_class, table, attribute, value)
         if record.persisted? && finder_class.primary_key.to_s != attribute.to_s
-          relation = relation.where.not(finder_class.primary_key => record.id)
+          if finder_class.primary_key
+            relation = relation.where.not(finder_class.primary_key => record.id)
+          else
+            raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.")
+          end
         end
         relation = scope_relation(record, table, relation)
         relation = relation.merge(options[:conditions]) if options[:conditions]
-- 
cgit v1.2.3


From 23dbe10f221fec406d95b70c9c0bfc06cd5fe2f4 Mon Sep 17 00:00:00 2001
From: Robert Eshleman <c.robert.eshleman@gmail.com>
Date: Thu, 20 Aug 2015 15:57:05 -0400
Subject: Fix Punctuation in `AutosaveAssociation` RDoc

[ci skip]
---
 activerecord/lib/active_record/autosave_association.rb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index dbb0e2fab2..d0de42d27c 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -234,7 +234,7 @@ module ActiveRecord
       super
     end
 
-    # Marks this record to be destroyed as part of the parents save transaction.
+    # Marks this record to be destroyed as part of the parent's save transaction.
     # This does _not_ actually destroy the record instantly, rather child record will be destroyed
     # when <tt>parent.save</tt> is called.
     #
@@ -243,7 +243,7 @@ module ActiveRecord
       @marked_for_destruction = true
     end
 
-    # Returns whether or not this record will be destroyed as part of the parents save transaction.
+    # Returns whether or not this record will be destroyed as part of the parent's save transaction.
     #
     # Only useful if the <tt>:autosave</tt> option on the parent is enabled for this associated model.
     def marked_for_destruction?
-- 
cgit v1.2.3


From 3088460df04a8060a099398904bcd0a3098a6bef Mon Sep 17 00:00:00 2001
From: Yves Senn <yves.senn@gmail.com>
Date: Fri, 21 Aug 2015 11:06:41 +0200
Subject: better docs for `disable_ddl_transaction!`. Closes #21044.

---
 activerecord/lib/active_record/migration.rb | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index b5b91451c7..c35efbdee8 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -409,7 +409,10 @@ module ActiveRecord
         new.migrate direction
       end
 
-      # Disable DDL transactions for this migration.
+      # Disable the transaction wrapping this migration.
+      # You can still create your own transactions even after calling #disable_ddl_transaction!
+      #
+      # For more details read the {"Transactional Migrations" section above}[rdoc-ref:Migration].
       def disable_ddl_transaction!
         @disable_ddl_transaction = true
       end
-- 
cgit v1.2.3


From ffc4710c2bff273b82ddb76675701f986d82ef4f Mon Sep 17 00:00:00 2001
From: Sean Griffin <sean@thoughtbot.com>
Date: Fri, 21 Aug 2015 17:45:46 -0600
Subject: JSON is still an adapter specific type.

Several changes were made in #21110 which I am strongly opposed to.
(this is what I get for going on vacation. :trollface:) No type should
be introduced into the generic `ActiveRecord::Type` namespace, and
*certainly* should not be registered into the registry unconstrained
unless it is supported by *all* adapters (which basically means that it
was specified in the ANSI SQL standard).

I do not think `# :nodoc:` ing the type is sufficient, as it still makes
the code of Rails itself very unclear as to what the role of that class
is. While I would argue that this shouldn't even be a super class, and
that MySql and PG's JSON types are only superficially duplicated (they
might look the same but will change for different reasons in the
future).

However, I don't feel strongly enough about it as a point of contention
(and the biggest cost of harming the blameability has already occured),
so I simply moved the superclass into a namespace where its role is
absolutely clear.

After this change, `attribute :foo, :json` will once again work with
MySQL and PG, but not with Sqlite3 or any third party adapters.

Unresolved questions
--------------------

The types that and adapter publishes (at least those are unique to that
adapter, and not adding additional behavior like `MysqlString` should
probably be part of the adapter's public API. Should we standardize the
namespace for these, and document them?
---
 .../connection_adapters/abstract_mysql_adapter.rb  |  2 +-
 .../connection_adapters/postgresql/oid.rb          |  1 +
 .../connection_adapters/postgresql/oid/json.rb     | 10 +++++++
 .../connection_adapters/postgresql/oid/jsonb.rb    |  2 +-
 .../connection_adapters/postgresql_adapter.rb      |  3 +-
 activerecord/lib/active_record/type.rb             |  4 +--
 .../active_record/type/internal/abstract_json.rb   | 33 ++++++++++++++++++++++
 activerecord/lib/active_record/type/json.rb        | 31 --------------------
 8 files changed, 50 insertions(+), 36 deletions(-)
 create mode 100644 activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb
 create mode 100644 activerecord/lib/active_record/type/internal/abstract_json.rb
 delete mode 100644 activerecord/lib/active_record/type/json.rb

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 96ea866580..b3e55a0b90 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -1050,7 +1050,7 @@ module ActiveRecord
         end
       end
 
-      class MysqlJson < Type::Json # :nodoc:
+      class MysqlJson < Type::Internal::AbstractJson # :nodoc:
         def changed_in_place?(raw_old_value, new_value)
           # Normalization is required because MySQL JSON data format includes
           # the space between the elements.
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index 37226831dc..68752cdd80 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -8,6 +8,7 @@ require 'active_record/connection_adapters/postgresql/oid/decimal'
 require 'active_record/connection_adapters/postgresql/oid/enum'
 require 'active_record/connection_adapters/postgresql/oid/hstore'
 require 'active_record/connection_adapters/postgresql/oid/inet'
+require 'active_record/connection_adapters/postgresql/oid/json'
 require 'active_record/connection_adapters/postgresql/oid/jsonb'
 require 'active_record/connection_adapters/postgresql/oid/money'
 require 'active_record/connection_adapters/postgresql/oid/point'
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb
new file mode 100644
index 0000000000..dbc879ffd4
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb
@@ -0,0 +1,10 @@
+module ActiveRecord
+  module ConnectionAdapters
+    module PostgreSQL
+      module OID # :nodoc:
+        class Json < Type::Internal::AbstractJson
+        end
+      end
+    end
+  end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
index 1f6d63582c..87391b5dc7 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
@@ -2,7 +2,7 @@ module ActiveRecord
   module ConnectionAdapters
     module PostgreSQL
       module OID # :nodoc:
-        class Jsonb < Type::Json # :nodoc:
+        class Jsonb < Json # :nodoc:
           def type
             :jsonb
           end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 861edbf3a2..27291bd2ea 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -482,7 +482,7 @@ module ActiveRecord
           m.register_type 'bytea', OID::Bytea.new
           m.register_type 'point', OID::Point.new
           m.register_type 'hstore', OID::Hstore.new
-          m.register_type 'json', Type::Json.new
+          m.register_type 'json', OID::Json.new
           m.register_type 'jsonb', OID::Jsonb.new
           m.register_type 'cidr', OID::Cidr.new
           m.register_type 'inet', OID::Inet.new
@@ -838,6 +838,7 @@ module ActiveRecord
         ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
         ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
         ActiveRecord::Type.register(:inet, OID::Inet, adapter: :postgresql)
+        ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
         ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
         ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
         ActiveRecord::Type.register(:point, OID::Point, adapter: :postgresql)
diff --git a/activerecord/lib/active_record/type.rb b/activerecord/lib/active_record/type.rb
index 8f56a37f3c..53f3b53bec 100644
--- a/activerecord/lib/active_record/type.rb
+++ b/activerecord/lib/active_record/type.rb
@@ -10,7 +10,6 @@ require 'active_record/type/decimal'
 require 'active_record/type/decimal_without_scale'
 require 'active_record/type/float'
 require 'active_record/type/integer'
-require 'active_record/type/json'
 require 'active_record/type/serialized'
 require 'active_record/type/string'
 require 'active_record/type/text'
@@ -21,6 +20,8 @@ require 'active_record/type/adapter_specific_registry'
 require 'active_record/type/type_map'
 require 'active_record/type/hash_lookup_type_map'
 
+require 'active_record/type/internal/abstract_json'
+
 module ActiveRecord
   module Type
     @registry = AdapterSpecificRegistry.new
@@ -60,7 +61,6 @@ module ActiveRecord
     register(:decimal, Type::Decimal, override: false)
     register(:float, Type::Float, override: false)
     register(:integer, Type::Integer, override: false)
-    register(:json, Type::Json, override: false)
     register(:string, Type::String, override: false)
     register(:text, Type::Text, override: false)
     register(:time, Type::Time, override: false)
diff --git a/activerecord/lib/active_record/type/internal/abstract_json.rb b/activerecord/lib/active_record/type/internal/abstract_json.rb
new file mode 100644
index 0000000000..963a8245d0
--- /dev/null
+++ b/activerecord/lib/active_record/type/internal/abstract_json.rb
@@ -0,0 +1,33 @@
+module ActiveRecord
+  module Type
+    module Internal # :nodoc:
+      class AbstractJson < Type::Value # :nodoc:
+        include Type::Helpers::Mutable
+
+        def type
+          :json
+        end
+
+        def deserialize(value)
+          if value.is_a?(::String)
+            ::ActiveSupport::JSON.decode(value) rescue nil
+          else
+            value
+          end
+        end
+
+        def serialize(value)
+          if value.is_a?(::Array) || value.is_a?(::Hash)
+            ::ActiveSupport::JSON.encode(value)
+          else
+            value
+          end
+        end
+
+        def accessor
+          ActiveRecord::Store::StringKeyedHashAccessor
+        end
+      end
+    end
+  end
+end
diff --git a/activerecord/lib/active_record/type/json.rb b/activerecord/lib/active_record/type/json.rb
deleted file mode 100644
index 1728bd3a8e..0000000000
--- a/activerecord/lib/active_record/type/json.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-module ActiveRecord
-  module Type
-    class Json < Type::Value # :nodoc:
-      include Type::Helpers::Mutable
-
-      def type
-        :json
-      end
-
-      def deserialize(value)
-        if value.is_a?(::String)
-          ::ActiveSupport::JSON.decode(value) rescue nil
-        else
-          value
-        end
-      end
-
-      def serialize(value)
-        if value.is_a?(::Array) || value.is_a?(::Hash)
-          ::ActiveSupport::JSON.encode(value)
-        else
-          value
-        end
-      end
-
-      def accessor
-        ActiveRecord::Store::StringKeyedHashAccessor
-      end
-    end
-  end
-end
-- 
cgit v1.2.3


From f9f156b22c77eb01c009eaac421afcb2a2d6673f Mon Sep 17 00:00:00 2001
From: Ronak Jangir <ronakjangir47@gmail.com>
Date: Sat, 22 Aug 2015 22:56:04 +0530
Subject: Added docs for CollectionProxy#take [ci skip]

---
 .../active_record/associations/collection_proxy.rb | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index b5a8c81fe4..29c711082a 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -227,6 +227,31 @@ module ActiveRecord
         @association.last(*args)
       end
 
+      # Gives a record (or N records if a parameter is supplied) from the collection
+      # using the same rules as <tt>ActiveRecord::Base.take</tt>.
+      #
+      #   class Person < ActiveRecord::Base
+      #     has_many :pets
+      #   end
+      #
+      #   person.pets
+      #   # => [
+      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
+      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+      #   #    ]
+      #
+      #   person.pets.take # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
+      #
+      #   person.pets.take(2)
+      #   # => [
+      #   #      #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+      #   #      #<Pet id: 2, name: "Spook", person_id: 1>
+      #   #    ]
+      #
+      #   another_person_without.pets         # => []
+      #   another_person_without.pets.take    # => nil
+      #   another_person_without.pets.take(2) # => []
       def take(n = nil)
         @association.take(n)
       end
-- 
cgit v1.2.3


From 3048f2f89f62b28591c4c9e40e0a23e88ff13e7f Mon Sep 17 00:00:00 2001
From: yui-knk <spiketeika@gmail.com>
Date: Sun, 23 Aug 2015 11:15:05 +0900
Subject: Remove not used a block argument (`&block`)

---
 activerecord/lib/active_record/migration.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index c35efbdee8..04c6124eef 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -814,7 +814,7 @@ module ActiveRecord
         new(:up, migrations, target_version).migrate
       end
 
-      def down(migrations_paths, target_version = nil, &block)
+      def down(migrations_paths, target_version = nil)
         migrations = migrations(migrations_paths)
         migrations.select! { |m| yield m } if block_given?
 
-- 
cgit v1.2.3