Hello community, here is the log from the commit of package rubygem-activerecord-4_2 for openSUSE:Factory checked in at 2015-07-05 18:02:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-activerecord-4_2 (Old) and /work/SRC/openSUSE:Factory/.rubygem-activerecord-4_2.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-activerecord-4_2" Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-activerecord-4_2/rubygem-activerecord-4_2.changes 2015-03-27 09:40:03.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.rubygem-activerecord-4_2.new/rubygem-activerecord-4_2.changes 2015-07-05 18:02:32.000000000 +0200 @@ -1,0 +2,130 @@ +Fri Jun 26 04:31:24 UTC 2015 - co...@suse.com + +- updated to version 4.2.3 + see installed CHANGELOG.md + + ## Rails 4.2.3 (June 25, 2015) ## + + * Let `WITH` queries (Common Table Expressions) be explainable. + + *Vladimir Kochnev* + + * Fix n+1 query problem when eager loading nil associations (fixes #18312) + + *Sammy Larbi* + + * Fixed an error which would occur in dirty checking when calling + `update_attributes` from a getter. + + Fixes #20531. + + *Sean Griffin* + + * Ensure symbols passed to `ActiveRecord::Relation#select` are always treated + as columns. + + Fixes #20360. + + *Sean Griffin* + + * Clear query cache when `ActiveRecord::Base#reload` is called. + + *Shane Hender* + + * Pass `:extend` option for `has_and_belongs_to_many` associations to the + underlying `has_many :through`. + + *Jaehyun Shin* + + * Make `unscope` aware of "less than" and "greater than" conditions. + + *TAKAHASHI Kazuaki* + + * Revert behavior of `db:schema:load` back to loading the full + environment. This ensures that initializers are run. + + Fixes #19545. + + *Yves Senn* + + * Fix missing index when using `timestamps` with the `index` option. + + The `index` option used with `timestamps` should be passed to both + `column` definitions for `created_at` and `updated_at` rather than just + the first. + + *Paul Mucur* + + * Rename `:class` to `:anonymous_class` in association options. + + Fixes #19659. + + *Andrew White* + + * Fixed a bug where uniqueness validations would error on out of range values, + even if an validation should have prevented it from hitting the database. + + *Andrey Voronkov* + + * Foreign key related methods in the migration DSL respect + `ActiveRecord::Base.pluralize_table_names = false`. + + Fixes #19643. + + *Mehmet Emin İNAÇ* + + * Reduce memory usage from loading types on pg. + + Fixes #19578. + + *Sean Griffin* + + * Fix referencing wrong table aliases while joining tables of has many through + association (only when calling calculation methods). + + Fixes #19276. + + *pinglamb* + + * Don't attempt to update counter caches, when the column wasn't selected. + + Fixes #19437. + + *Sean Griffin* + + * Correctly persist a serialized attribute that has been returned to + its default value by an in-place modification. + + Fixes #19467. + + *Matthew Draper* + + * Fix default `format` value in `ActiveRecord::Tasks::DatabaseTasks#schema_file`. + + *James Cox* + + * Dont enroll records in the transaction if they dont have commit callbacks. + That was causing a memory grow problem when creating a lot of records inside a transaction. + + Fixes #15549. + + *Will Bryant*, *Aaron Patterson* + + * Correctly create through records when created on a has many through + association when using `where`. + + Fixes #19073. + + *Sean Griffin* + +------------------------------------------------------------------- +Wed Jun 17 04:32:38 UTC 2015 - co...@suse.com + +- updated to version 4.2.2 + see installed CHANGELOG.md + + ## Rails 4.2.2 (June 16, 2015) ## + + * No Changes * + +------------------------------------------------------------------- Old: ---- activerecord-4.2.1.gem New: ---- activerecord-4.2.3.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-activerecord-4_2.spec ++++++ --- /var/tmp/diff_new_pack.zxlx7c/_old 2015-07-05 18:02:33.000000000 +0200 +++ /var/tmp/diff_new_pack.zxlx7c/_new 2015-07-05 18:02:33.000000000 +0200 @@ -24,7 +24,7 @@ # Name: rubygem-activerecord-4_2 -Version: 4.2.1 +Version: 4.2.3 Release: 0 %define mod_name activerecord %define mod_full_name %{mod_name}-%{version} ++++++ activerecord-4.2.1.gem -> activerecord-4.2.3.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md --- old/CHANGELOG.md 2015-03-19 17:40:46.000000000 +0100 +++ new/CHANGELOG.md 2015-06-25 23:29:22.000000000 +0200 @@ -1,4 +1,124 @@ -## Rails 4.2.1 (March 19, 2014) ## +## Rails 4.2.3 (June 25, 2015) ## + +* Let `WITH` queries (Common Table Expressions) be explainable. + + *Vladimir Kochnev* + +* Fix n+1 query problem when eager loading nil associations (fixes #18312) + + *Sammy Larbi* + +* Fixed an error which would occur in dirty checking when calling + `update_attributes` from a getter. + + Fixes #20531. + + *Sean Griffin* + +* Ensure symbols passed to `ActiveRecord::Relation#select` are always treated + as columns. + + Fixes #20360. + + *Sean Griffin* + +* Clear query cache when `ActiveRecord::Base#reload` is called. + + *Shane Hender* + +* Pass `:extend` option for `has_and_belongs_to_many` associations to the + underlying `has_many :through`. + + *Jaehyun Shin* + +* Make `unscope` aware of "less than" and "greater than" conditions. + + *TAKAHASHI Kazuaki* + +* Revert behavior of `db:schema:load` back to loading the full + environment. This ensures that initializers are run. + + Fixes #19545. + + *Yves Senn* + +* Fix missing index when using `timestamps` with the `index` option. + + The `index` option used with `timestamps` should be passed to both + `column` definitions for `created_at` and `updated_at` rather than just + the first. + + *Paul Mucur* + +* Rename `:class` to `:anonymous_class` in association options. + + Fixes #19659. + + *Andrew White* + +* Fixed a bug where uniqueness validations would error on out of range values, + even if an validation should have prevented it from hitting the database. + + *Andrey Voronkov* + +* Foreign key related methods in the migration DSL respect + `ActiveRecord::Base.pluralize_table_names = false`. + + Fixes #19643. + + *Mehmet Emin İNAÇ* + +* Reduce memory usage from loading types on pg. + + Fixes #19578. + + *Sean Griffin* + +* Fix referencing wrong table aliases while joining tables of has many through + association (only when calling calculation methods). + + Fixes #19276. + + *pinglamb* + +* Don't attempt to update counter caches, when the column wasn't selected. + + Fixes #19437. + + *Sean Griffin* + +* Correctly persist a serialized attribute that has been returned to + its default value by an in-place modification. + + Fixes #19467. + + *Matthew Draper* + +* Fix default `format` value in `ActiveRecord::Tasks::DatabaseTasks#schema_file`. + + *James Cox* + +* Dont enroll records in the transaction if they dont have commit callbacks. + That was causing a memory grow problem when creating a lot of records inside a transaction. + + Fixes #15549. + + *Will Bryant*, *Aaron Patterson* + +* Correctly create through records when created on a has many through + association when using `where`. + + Fixes #19073. + + *Sean Griffin* + + +## Rails 4.2.2 (June 16, 2015) ## + +* No Changes * + + +## Rails 4.2.1 (March 19, 2015) ## * Fixed ActiveRecord::Relation#becomes! and changed_attributes issues for type column Files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/association_relation.rb new/lib/active_record/association_relation.rb --- old/lib/active_record/association_relation.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/association_relation.rb 2015-06-25 23:29:22.000000000 +0200 @@ -13,6 +13,19 @@ other == to_a end + def build(*args, &block) + scoping { @association.build(*args, &block) } + end + alias new build + + def create(*args, &block) + scoping { @association.create(*args, &block) } + end + + def create!(*args, &block) + scoping { @association.create!(*args, &block) } + end + private def exec_queries diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/belongs_to_association.rb new/lib/active_record/associations/belongs_to_association.rb --- old/lib/active_record/associations/belongs_to_association.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/associations/belongs_to_association.rb 2015-06-25 23:29:22.000000000 +0200 @@ -68,7 +68,7 @@ def increment_counter(counter_cache_name) if foreign_key_present? klass.increment_counter(counter_cache_name, target_id) - if target && !stale_target? + if target && !stale_target? && counter_cache_available_in_memory?(counter_cache_name) target.increment(counter_cache_name) end end @@ -110,6 +110,10 @@ result = owner._read_attribute(reflection.foreign_key) result && result.to_s end + + def counter_cache_available_in_memory?(counter_cache_name) + target.respond_to?(counter_cache_name) + end end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/builder/association.rb new/lib/active_record/associations/builder/association.rb --- old/lib/active_record/associations/builder/association.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/associations/builder/association.rb 2015-06-25 23:29:22.000000000 +0200 @@ -21,7 +21,7 @@ end self.extensions = [] - self.valid_options = [:class_name, :class, :foreign_key, :validate] + self.valid_options = [:class_name, :anonymous_class, :foreign_key, :validate] attr_reader :name, :scope, :options diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/builder/has_and_belongs_to_many.rb new/lib/active_record/associations/builder/has_and_belongs_to_many.rb --- old/lib/active_record/associations/builder/has_and_belongs_to_many.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/associations/builder/has_and_belongs_to_many.rb 2015-06-25 23:29:22.000000000 +0200 @@ -78,7 +78,7 @@ join_model.table_name_resolver = habtm join_model.class_resolver = lhs_model - join_model.add_left_association :left_side, class: lhs_model + join_model.add_left_association :left_side, anonymous_class: lhs_model join_model.add_right_association association_name, belongs_to_options(options) join_model end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/collection_proxy.rb new/lib/active_record/associations/collection_proxy.rb --- old/lib/active_record/associations/collection_proxy.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/associations/collection_proxy.rb 2015-06-25 23:29:22.000000000 +0200 @@ -470,15 +470,16 @@ @association.destroy_all end - # Deletes the +records+ supplied and removes them from the collection. For - # +has_many+ associations, the deletion is done according to the strategy - # specified by the <tt>:dependent</tt> option. Returns an array with the + # Deletes the +records+ supplied from the collection according to the strategy + # specified by the +:dependent+ option. If no +:dependent+ option is given, + # then it will follow the default strategy. Returns an array with the # deleted records. # - # If no <tt>:dependent</tt> option is given, then it will follow the default - # strategy. The default strategy is <tt>:nullify</tt>. This sets the foreign - # keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>, the default - # strategy is +delete_all+. + # For +has_many :through+ associations, the default deletion strategy is + # +:delete_all+. + # + # For +has_many+ associations, the default deletion strategy is +:nullify+. + # This sets the foreign keys to +NULL+. # # class Person < ActiveRecord::Base # has_many :pets # dependent: :nullify option by default diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/has_many_through_association.rb new/lib/active_record/associations/has_many_through_association.rb --- old/lib/active_record/associations/has_many_through_association.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/associations/has_many_through_association.rb 2015-06-25 23:29:22.000000000 +0200 @@ -162,7 +162,7 @@ count = scope.destroy_all.length else scope.each do |record| - record._run_destroy_callbacks + record.run_callbacks :destroy end arel = scope.arel diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/join_dependency.rb new/lib/active_record/associations/join_dependency.rb --- old/lib/active_record/associations/join_dependency.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/associations/join_dependency.rb 2015-06-25 23:29:22.000000000 +0200 @@ -233,6 +233,7 @@ end def construct(ar_parent, parent, row, rs, seen, model_cache, aliases) + return if ar_parent.nil? primary_id = ar_parent.id parent.children.each do |node| @@ -249,7 +250,11 @@ key = aliases.column_alias(node, node.primary_key) id = row[key] - next if id.nil? + if id.nil? + nil_association = ar_parent.association(node.reflection.name) + nil_association.loaded! + next + end model = seen[parent.base_klass][primary_id][node.base_klass][id] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/through_association.rb new/lib/active_record/associations/through_association.rb --- old/lib/active_record/associations/through_association.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/associations/through_association.rb 2015-06-25 23:29:22.000000000 +0200 @@ -18,7 +18,7 @@ reflection_scope = reflection.scope if reflection_scope && reflection_scope.arity.zero? - relation.merge!(reflection_scope) + relation = relation.merge(reflection_scope) end scope.merge!( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations.rb new/lib/active_record/associations.rb --- old/lib/active_record/associations.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/associations.rb 2015-06-25 23:29:22.000000000 +0200 @@ -1713,7 +1713,7 @@ hm_options[:through] = middle_reflection.name hm_options[:source] = join_model.right_reflection.name - [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name].each do |k| + [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend].each do |k| hm_options[k] = options[k] if options.key? k end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/attribute_assignment.rb new/lib/active_record/attribute_assignment.rb --- old/lib/active_record/attribute_assignment.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/attribute_assignment.rb 2015-06-25 23:29:22.000000000 +0200 @@ -52,7 +52,7 @@ def _assign_attribute(k, v) public_send("#{k}=", v) - rescue NoMethodError + rescue NoMethodError, NameError if respond_to?("#{k}=") raise else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/attribute_methods/dirty.rb new/lib/active_record/attribute_methods/dirty.rb --- old/lib/active_record/attribute_methods/dirty.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/attribute_methods/dirty.rb 2015-06-25 23:29:22.000000000 +0200 @@ -108,6 +108,7 @@ end def save_changed_attribute(attr, old_value) + clear_changed_attributes_cache if attribute_changed_by_setter?(attr) clear_attribute_changes(attr) unless _field_changed?(attr, old_value) else @@ -178,7 +179,11 @@ @cached_changed_attributes = changed_attributes yield ensure - remove_instance_variable(:@cached_changed_attributes) + clear_changed_attributes_cache + end + + def clear_changed_attributes_cache + remove_instance_variable(:@cached_changed_attributes) if defined?(@cached_changed_attributes) end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/base.rb new/lib/active_record/base.rb --- old/lib/active_record/base.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/base.rb 2015-06-25 23:29:22.000000000 +0200 @@ -119,23 +119,22 @@ # All column values are automatically available through basic accessors on the Active Record # object, but sometimes you want to specialize this behavior. This can be done by overwriting # the default accessors (using the same name as the attribute) and calling - # <tt>read_attribute(attr_name)</tt> and <tt>write_attribute(attr_name, value)</tt> to actually - # change things. + # +super+ to actually change things. # # class Song < ActiveRecord::Base # # Uses an integer of seconds to hold the length of the song # # def length=(minutes) - # write_attribute(:length, minutes.to_i * 60) + # super(minutes.to_i * 60) # end # # def length - # read_attribute(:length) / 60 + # super / 60 # end # end # # You can alternatively use <tt>self[:attribute]=(value)</tt> and <tt>self[:attribute]</tt> - # instead of <tt>write_attribute(:attribute, value)</tt> and <tt>read_attribute(:attribute)</tt>. + # or <tt>write_attribute(:attribute, value)</tt> and <tt>read_attribute(:attribute)</tt>. # # == Attribute query methods # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/callbacks.rb new/lib/active_record/callbacks.rb --- old/lib/active_record/callbacks.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/callbacks.rb 2015-06-25 23:29:22.000000000 +0200 @@ -199,7 +199,7 @@ # == Canceling callbacks # # If a <tt>before_*</tt> callback returns +false+, all the later callbacks and the associated action are - # cancelled. If an <tt>after_*</tt> callback returns +false+, all the later callbacks are cancelled. + # cancelled. # Callbacks are generally run in the order they are defined, with the exception of callbacks defined as # methods on the model, which are called last. # @@ -289,25 +289,25 @@ end def destroy #:nodoc: - _run_destroy_callbacks { super } + run_callbacks(:destroy) { super } end def touch(*) #:nodoc: - _run_touch_callbacks { super } + run_callbacks(:touch) { super } end private def create_or_update #:nodoc: - _run_save_callbacks { super } + run_callbacks(:save) { super } end def _create_record #:nodoc: - _run_create_callbacks { super } + run_callbacks(:create) { super } end def _update_record(*) #:nodoc: - _run_update_callbacks { super } + run_callbacks(:update) { super } end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract/connection_pool.rb new/lib/active_record/connection_adapters/abstract/connection_pool.rb --- old/lib/active_record/connection_adapters/abstract/connection_pool.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/abstract/connection_pool.rb 2015-06-25 23:29:22.000000000 +0200 @@ -361,7 +361,7 @@ synchronize do owner = conn.owner - conn._run_checkin_callbacks do + conn.run_callbacks :checkin do conn.expire end @@ -452,10 +452,14 @@ end def checkout_and_verify(c) - c._run_checkout_callbacks do + c.run_callbacks :checkout do c.verify! end c + rescue + remove c + c.disconnect! + raise end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract/database_statements.rb new/lib/active_record/connection_adapters/abstract/database_statements.rb --- old/lib/active_record/connection_adapters/abstract/database_statements.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/abstract/database_statements.rb 2015-06-25 23:29:22.000000000 +0200 @@ -234,6 +234,10 @@ current_transaction.add_record(record) end + def transaction_state + current_transaction.state + end + # Begins the transaction (and turns off auto-committing). def begin_db_transaction() end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract/schema_definitions.rb new/lib/active_record/connection_adapters/abstract/schema_definitions.rb --- old/lib/active_record/connection_adapters/abstract/schema_definitions.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/abstract/schema_definitions.rb 2015-06-25 23:29:22.000000000 +0200 @@ -57,11 +57,11 @@ end module TimestampDefaultDeprecation # :nodoc: - def emit_warning_if_null_unspecified(options) + def emit_warning_if_null_unspecified(sym, options) return if options.key?(:null) ActiveSupport::Deprecation.warn(<<-MSG.squish) - `#timestamp` was called without specifying an option for `null`. In Rails 5, + `##{sym}` was called without specifying an option for `null`. In Rails 5, this behavior will change to `null: false`. You should manually specify `null: true` to prevent the behavior of your existing migrations from changing. MSG @@ -256,6 +256,7 @@ def column(name, type, options = {}) name = name.to_s type = type.to_sym + options = options.dup if @columns_hash[name] && @columns_hash[name].primary_key? raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table." @@ -297,23 +298,17 @@ # t.timestamps null: false def timestamps(*args) options = args.extract_options! - emit_warning_if_null_unspecified(options) + emit_warning_if_null_unspecified(:timestamps, options) column(:created_at, :datetime, options) column(:updated_at, :datetime, options) end - # Adds a reference. Optionally adds a +type+ column, if - # <tt>:polymorphic</tt> option is provided. <tt>references</tt> and - # <tt>belongs_to</tt> are acceptable. The reference column will be an - # +integer+ by default, the <tt>:type</tt> option can be used to specify - # a different type. A foreign key will be created if a +foreign_key+ - # option is passed. + # Adds a reference. # # t.references(:user) - # t.references(:user, type: "string") - # t.belongs_to(:supplier, polymorphic: true) + # t.belongs_to(:supplier, foreign_key: true) # - # See SchemaStatements#add_reference + # See SchemaStatements#add_reference for details of the options you can use. def references(*args) options = args.extract_options! polymorphic = options.delete(:polymorphic) @@ -329,7 +324,10 @@ column("#{col}_id", type, options) column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic index(polymorphic ? %w(type id).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options - foreign_key(col.to_s.pluralize, foreign_key_options.is_a?(Hash) ? foreign_key_options : {}) if foreign_key_options + if foreign_key_options + to_table = Base.pluralize_table_names ? col.to_s.pluralize : col.to_s + foreign_key(to_table, foreign_key_options.is_a?(Hash) ? foreign_key_options : {}) + end end end alias :belongs_to :references @@ -535,18 +533,12 @@ @base.rename_column(name, column_name, new_column_name) end - # Adds a reference. Optionally adds a +type+ column, if - # <tt>:polymorphic</tt> option is provided. <tt>references</tt> and - # <tt>belongs_to</tt> are acceptable. The reference column will be an - # +integer+ by default, the <tt>:type</tt> option can be used to specify - # a different type. A foreign key will be created if a +foreign_key+ - # option is passed. + # Adds a reference. # # t.references(:user) - # t.references(:user, type: "string") - # t.belongs_to(:supplier, polymorphic: true) + # t.belongs_to(:supplier, foreign_key: true) # - # See SchemaStatements#add_reference + # See SchemaStatements#add_reference for details of the options you can use. def references(*args) options = args.extract_options! args.each do |ref_name| diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract/schema_statements.rb new/lib/active_record/connection_adapters/abstract/schema_statements.rb --- old/lib/active_record/connection_adapters/abstract/schema_statements.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/abstract/schema_statements.rb 2015-06-25 23:29:22.000000000 +0200 @@ -530,6 +530,8 @@ # # CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active # + # Note: Partial indexes are only supported for PostgreSQL and SQLite 3.8.0+. + # # ====== Creating an index with a specific method # # add_index(:developers, :name, using: 'btree') @@ -621,11 +623,21 @@ indexes(table_name).detect { |i| i.name == index_name } end - # Adds a reference. Optionally adds a +type+ column, if <tt>:polymorphic</tt> option is provided. - # The reference column is an +integer+ by default, the <tt>:type</tt> option can be used to specify - # a different type. + # Adds a reference. The reference column is an integer by default, + # the <tt>:type</tt> option can be used to specify a different type. + # Optionally adds a +_type+ column, if <tt>:polymorphic</tt> option is provided. # <tt>add_reference</tt> and <tt>add_belongs_to</tt> are acceptable. # + # The +options+ hash can include the following keys: + # [<tt>:type</tt>] + # The reference column type. Defaults to +:integer+. + # [<tt>:index</tt>] + # Add an appropriate index. Defaults to false. + # [<tt>:foreign_key</tt>] + # Add an appropriate foreign key. Defaults to false. + # [<tt>:polymorphic</tt>] + # Wether an additional +_type+ column should be added. Defaults to false. + # # ====== Create a user_id integer column # # add_reference(:products, :user) @@ -634,10 +646,6 @@ # # add_reference(:products, :user, type: :string) # - # ====== Create a supplier_id and supplier_type columns - # - # add_belongs_to(:products, :supplier, polymorphic: true) - # # ====== Create supplier_id, supplier_type columns and appropriate index # # add_reference(:products, :supplier, polymorphic: true, index: true) @@ -655,7 +663,10 @@ add_column(table_name, "#{ref_name}_id", type, options) add_column(table_name, "#{ref_name}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic add_index(table_name, polymorphic ? %w[type id].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options - add_foreign_key(table_name, ref_name.to_s.pluralize, foreign_key_options.is_a?(Hash) ? foreign_key_options : {}) if foreign_key_options + if foreign_key_options + to_table = Base.pluralize_table_names ? ref_name.to_s.pluralize : ref_name + add_foreign_key(table_name, to_table, foreign_key_options.is_a?(Hash) ? foreign_key_options : {}) + end end alias :add_belongs_to :add_reference @@ -675,7 +686,10 @@ # remove_reference(:products, :user, index: true, foreign_key: true) # def remove_reference(table_name, ref_name, options = {}) - remove_foreign_key table_name, ref_name.to_s.pluralize if options[:foreign_key] + if options[:foreign_key] + to_table = Base.pluralize_table_names ? ref_name.to_s.pluralize : ref_name + remove_foreign_key(table_name, to_table) + end remove_column(table_name, "#{ref_name}_id") remove_column(table_name, "#{ref_name}_type") if options[:polymorphic] @@ -692,8 +706,8 @@ # +to_table+ contains the referenced primary key. # # The foreign key will be named after the following pattern: <tt>fk_rails_<identifier></tt>. - # +identifier+ is a 10 character long random string. A custom name can be specified with - # the <tt>:name</tt> option. + # +identifier+ is a 10 character long string which is deterministically generated from the + # +from_table+ and +column+. A custom name can be specified with the <tt>:name</tt> option. # # ====== Creating a simple foreign key # @@ -705,7 +719,7 @@ # # ====== Creating a foreign key on a specific column # - # add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id" + # add_foreign_key :articles, :users, column: :author_id, primary_key: :lng_id # # generates: # @@ -874,7 +888,7 @@ # add_timestamps(:suppliers, null: false) # def add_timestamps(table_name, options = {}) - emit_warning_if_null_unspecified(options) + emit_warning_if_null_unspecified(:add_timestamps, options) add_column table_name, :created_at, :datetime, options add_column table_name, :updated_at, :datetime, options end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract/transaction.rb new/lib/active_record/connection_adapters/abstract/transaction.rb --- old/lib/active_record/connection_adapters/abstract/transaction.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/abstract/transaction.rb 2015-06-25 23:29:22.000000000 +0200 @@ -55,11 +55,7 @@ end def add_record(record) - if record.has_transactional_callbacks? - records << record - else - record.set_transaction_state(@state) - end + records << record end def rollback diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract_mysql_adapter.rb new/lib/active_record/connection_adapters/abstract_mysql_adapter.rb --- old/lib/active_record/connection_adapters/abstract_mysql_adapter.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/abstract_mysql_adapter.rb 2015-06-25 23:29:22.000000000 +0200 @@ -58,6 +58,12 @@ SchemaCreation.new self end + def prepare_column_options(column, types) # :nodoc: + spec = super + spec.delete(:limit) if :boolean === column.type + spec + end + class Column < ConnectionAdapters::Column # :nodoc: attr_reader :collation, :strict, :extra diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/mysql_adapter.rb new/lib/active_record/connection_adapters/mysql_adapter.rb --- old/lib/active_record/connection_adapters/mysql_adapter.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/mysql_adapter.rb 2015-06-25 23:29:22.000000000 +0200 @@ -57,7 +57,7 @@ # * <tt>:database</tt> - The name of the database. No default, must be provided. # * <tt>:encoding</tt> - (Optional) Sets the client encoding by executing "SET NAMES <encoding>" after connection. # * <tt>:reconnect</tt> - Defaults to false (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html). - # * <tt>:strict</tt> - Defaults to true. Enable STRICT_ALL_TABLES. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html) + # * <tt>:strict</tt> - Defaults to true. Enable STRICT_ALL_TABLES. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/sql-mode.html) # * <tt>:variables</tt> - (Optional) A hash session variables to send as <tt>SET @@SESSION.key = value</tt> on each database connection. Use the value +:default+ to set a variable to its DEFAULT value. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/set-statement.html). # * <tt>:sslca</tt> - Necessary to use MySQL with an SSL connection. # * <tt>:sslkey</tt> - Necessary to use MySQL with an SSL connection. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/postgresql/oid/enum.rb new/lib/active_record/connection_adapters/postgresql/oid/enum.rb --- old/lib/active_record/connection_adapters/postgresql/oid/enum.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/postgresql/oid/enum.rb 2015-06-25 23:29:22.000000000 +0200 @@ -7,7 +7,9 @@ :enum end - def type_cast(value) + private + + def cast_value(value) value.to_s end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb new/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb --- old/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb 2015-06-25 23:29:22.000000000 +0200 @@ -15,11 +15,11 @@ def run(records) nodes = records.reject { |row| @store.key? row['oid'].to_i } mapped, nodes = nodes.partition { |row| @store.key? row['typname'] } - ranges, nodes = nodes.partition { |row| row['typtype'] == 'r' } - enums, nodes = nodes.partition { |row| row['typtype'] == 'e' } - domains, nodes = nodes.partition { |row| row['typtype'] == 'd' } - arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in' } - composites, nodes = nodes.partition { |row| row['typelem'] != '0' } + ranges, nodes = nodes.partition { |row| row['typtype'] == 'r'.freeze } + enums, nodes = nodes.partition { |row| row['typtype'] == 'e'.freeze } + domains, nodes = nodes.partition { |row| row['typtype'] == 'd'.freeze } + arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in'.freeze } + composites, nodes = nodes.partition { |row| row['typelem'].to_i != 0 } mapped.each { |row| register_mapped_type(row) } enums.each { |row| register_enum_type(row) } @@ -29,6 +29,18 @@ composites.each { |row| register_composite_type(row) } end + def query_conditions_for_initial_load(type_map) + known_type_names = type_map.keys.map { |n| "'#{n}'" } + known_type_types = %w('r' 'e' 'd') + <<-SQL % [known_type_names.join(", "), known_type_types.join(", ")] + WHERE + t.typname IN (%s) + OR t.typtype IN (%s) + OR t.typinput::varchar = 'array_in' + OR t.typelem != 0 + SQL + end + private def register_mapped_type(row) alias_type row['oid'], row['typname'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/postgresql/schema_statements.rb new/lib/active_record/connection_adapters/postgresql/schema_statements.rb --- old/lib/active_record/connection_adapters/postgresql/schema_statements.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/postgresql/schema_statements.rb 2015-06-25 23:29:22.000000000 +0200 @@ -418,9 +418,7 @@ rename_table_indexes(table_name, new_name) end - # Adds a new column to the named table. - # See TableDefinition#column for details of the options you can use. - def add_column(table_name, column_name, type, options = {}) + def add_column(table_name, column_name, type, options = {}) #:nodoc: clear_cache! super end @@ -468,7 +466,7 @@ end # Renames a column in a table. - def rename_column(table_name, column_name, new_column_name) + def rename_column(table_name, column_name, new_column_name) #:nodoc: clear_cache! execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}" rename_column_indexes(table_name, column_name, new_column_name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/postgresql_adapter.rb new/lib/active_record/connection_adapters/postgresql_adapter.rb --- old/lib/active_record/connection_adapters/postgresql_adapter.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/connection_adapters/postgresql_adapter.rb 2015-06-25 23:29:22.000000000 +0200 @@ -556,6 +556,8 @@ end def load_additional_types(type_map, oids = nil) # :nodoc: + initializer = OID::TypeMapInitializer.new(type_map) + if supports_ranges? query = <<-SQL SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype @@ -571,11 +573,13 @@ if oids query += "WHERE t.oid::integer IN (%s)" % oids.join(", ") + else + query += initializer.query_conditions_for_initial_load(type_map) end - initializer = OID::TypeMapInitializer.new(type_map) - records = execute(query, 'SCHEMA') - initializer.run(records) + execute_and_clear(query, 'SCHEMA', []) do |records| + initializer.run(records) + end end FEATURE_NOT_SUPPORTED = "0A000" #:nodoc: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/core.rb new/lib/active_record/core.rb --- old/lib/active_record/core.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/core.rb 2015-06-25 23:29:22.000000000 +0200 @@ -281,18 +281,22 @@ init_attributes(attributes, options) if attributes yield self if block_given? - _run_initialize_callbacks + run_callbacks :initialize end - # Initialize an empty model object from +coder+. +coder+ must contain - # the attributes necessary for initializing an empty model object. For - # example: + # Initialize an empty model object from +coder+. +coder+ should be + # the result of previously encoding an Active Record model, using + # `encode_with` # # class Post < ActiveRecord::Base # end # + # old_post = Post.new(title: "hello world") + # coder = {} + # old_post.encode_with(coder) + # # post = Post.allocate - # post.init_with('attributes' => { 'title' => 'hello world' }) + # post.init_with(coder) # post.title # => 'hello world' def init_with(coder) @attributes = coder['attributes'] @@ -303,8 +307,8 @@ self.class.define_attribute_methods - _run_find_callbacks - _run_initialize_callbacks + run_callbacks :find + run_callbacks :initialize self end @@ -340,7 +344,7 @@ @attributes = @attributes.dup @attributes.reset(self.class.primary_key) - _run_initialize_callbacks + run_callbacks(:initialize) @aggregation_cache = {} @association_cache = {} @@ -479,16 +483,16 @@ Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access end + private + def set_transaction_state(state) # :nodoc: @transaction_state = state end def has_transactional_callbacks? # :nodoc: - !_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_create_callbacks.empty? + !_rollback_callbacks.empty? || !_commit_callbacks.empty? end - private - # Updates the attributes on this particular ActiveRecord object so that # if it is associated with a transaction, then the state of the AR object # will be updated to reflect the current state of the transaction @@ -511,6 +515,8 @@ end def update_attributes_from_transaction_state(transaction_state, depth) + @reflects_state = [false] if depth == 0 + if transaction_state && transaction_state.finalized? && !has_transactional_callbacks? unless @reflects_state[depth] restore_transaction_record_state if transaction_state.rolledback? @@ -547,7 +553,6 @@ @txn = nil @_start_transaction_state = {} @transaction_state = nil - @reflects_state = [false] end def initialize_internals_callback diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/errors.rb new/lib/active_record/errors.rb --- old/lib/active_record/errors.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/errors.rb 2015-06-25 23:29:22.000000000 +0200 @@ -71,9 +71,9 @@ class RecordNotDestroyed < ActiveRecordError attr_reader :record - def initialize(record) + def initialize(message, record = nil) @record = record - super() + super(message) end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/explain_subscriber.rb new/lib/active_record/explain_subscriber.rb --- old/lib/active_record/explain_subscriber.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/explain_subscriber.rb 2015-06-25 23:29:22.000000000 +0200 @@ -19,7 +19,7 @@ # On the other hand, we want to monitor the performance of our real database # queries, not the performance of the access to the query cache. IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN CACHE) - EXPLAINED_SQLS = /\A\s*(select|update|delete|insert)\b/i + EXPLAINED_SQLS = /\A\s*(with|select|update|delete|insert)\b/i def ignore_payload?(payload) payload[:exception] || IGNORED_PAYLOADS.include?(payload[:name]) || payload[:sql] !~ EXPLAINED_SQLS end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/fixtures.rb new/lib/active_record/fixtures.rb --- old/lib/active_record/fixtures.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/fixtures.rb 2015-06-25 23:29:22.000000000 +0200 @@ -534,12 +534,10 @@ conn.insert_fixture(row, fixture_set_name) end end - end - # Cap primary key sequences to max(pk). - if connection.respond_to?(:reset_pk_sequence!) - fixture_sets.each do |fs| - connection.reset_pk_sequence!(fs.table_name) + # Cap primary key sequences to max(pk). + if conn.respond_to?(:reset_pk_sequence!) + conn.reset_pk_sequence!(fs.table_name) end end end @@ -661,7 +659,7 @@ row[association.foreign_type] = $1 end - fk_type = association.active_record.columns_hash[fk_name].type + fk_type = reflection_class.columns_hash[fk_name].type row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type) end when :has_many @@ -703,6 +701,10 @@ def lhs_key @association.through_reflection.foreign_key end + + def join_table + @association.through_reflection.table_name + end end private diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/gem_version.rb new/lib/active_record/gem_version.rb --- old/lib/active_record/gem_version.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/gem_version.rb 2015-06-25 23:29:22.000000000 +0200 @@ -7,7 +7,7 @@ module VERSION MAJOR = 4 MINOR = 2 - TINY = 1 + TINY = 3 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/migration.rb new/lib/active_record/migration.rb --- old/lib/active_record/migration.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/migration.rb 2015-06-25 23:29:22.000000000 +0200 @@ -307,9 +307,8 @@ # # == Reversible Migrations # - # Starting with Rails 3.1, you will be able to define reversible migrations. # Reversible migrations are migrations that know how to go +down+ for you. - # You simply supply the +up+ logic, and the Migration system will figure out + # You simply supply the +up+ logic, and the Migration system figures out # how to execute the down commands for you. # # To define a reversible migration, define the +change+ method in your diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/persistence.rb new/lib/active_record/persistence.rb --- old/lib/active_record/persistence.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/persistence.rb 2015-06-25 23:29:22.000000000 +0200 @@ -139,7 +139,7 @@ # Attributes marked as readonly are silently ignored if the record is # being updated. def save!(*) - create_or_update || raise(RecordNotSaved.new(nil, self)) + create_or_update || raise(RecordNotSaved.new("Failed to save the record", self)) end # Deletes the record in the database and freezes this instance to @@ -168,6 +168,7 @@ def destroy raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly? destroy_associations + self.class.connection.add_transaction_record(self) destroy_row if persisted? @destroyed = true freeze @@ -181,7 +182,7 @@ # and <tt>destroy!</tt> raises ActiveRecord::RecordNotDestroyed. See # ActiveRecord::Callbacks for further details. def destroy! - destroy || raise(ActiveRecord::RecordNotDestroyed, self) + destroy || raise(RecordNotDestroyed.new("Failed to destroy the record", self)) end # Returns an instance of the specified +klass+ with the attributes of the @@ -368,7 +369,7 @@ # # => #<Account id: 1, email: 'acco...@example.com'> # # Attributes are reloaded from the database, and caches busted, in - # particular the associations cache. + # particular the associations cache and the QueryCache. # # If the record no longer exists in the database <tt>ActiveRecord::RecordNotFound</tt> # is raised. Otherwise, in addition to the in-place modification the method @@ -406,6 +407,7 @@ def reload(options = nil) clear_aggregation_cache clear_association_cache + self.class.connection.clear_query_cache fresh_object = if options && options[:lock] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/railties/databases.rake new/lib/active_record/railties/databases.rake --- old/lib/active_record/railties/databases.rake 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/railties/databases.rake 2015-06-25 23:29:22.000000000 +0200 @@ -240,7 +240,7 @@ end desc 'Load a schema.rb file into the database' - task :load => [:load_config] do + task :load => [:environment, :load_config] do ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:ruby, ENV['SCHEMA']) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/reflection.rb new/lib/active_record/reflection.rb --- old/lib/active_record/reflection.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/reflection.rb 2015-06-25 23:29:22.000000000 +0200 @@ -196,7 +196,7 @@ @scope = scope @options = options @active_record = active_record - @klass = options[:class] + @klass = options[:anonymous_class] @plural_name = active_record.pluralize_table_names ? name.to_s.pluralize : name.to_s end @@ -632,7 +632,7 @@ def initialize(delegate_reflection) @delegate_reflection = delegate_reflection - @klass = delegate_reflection.options[:class] + @klass = delegate_reflection.options[:anonymous_class] @source_reflection_name = delegate_reflection.options[:source] end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/relation/delegation.rb new/lib/active_record/relation/delegation.rb --- old/lib/active_record/relation/delegation.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/relation/delegation.rb 2015-06-25 23:29:23.000000000 +0200 @@ -40,7 +40,7 @@ BLACKLISTED_ARRAY_METHODS = [ :compact!, :flatten!, :reject!, :reverse!, :rotate!, :map!, :shuffle!, :slice!, :sort!, :sort_by!, :delete_if, - :keep_if, :pop, :shift, :delete_at, :compact, :select! + :keep_if, :pop, :shift, :delete_at, :select! ].to_set # :nodoc: delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join, to: :to_a diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/relation/finder_methods.rb new/lib/active_record/relation/finder_methods.rb --- old/lib/active_record/relation/finder_methods.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/relation/finder_methods.rb 2015-06-25 23:29:23.000000000 +0200 @@ -114,23 +114,11 @@ # Find the first record (or first N records if a parameter is supplied). # If no order is defined it will order by primary key. # - # Person.first # returns the first object fetched by SELECT * FROM people + # Person.first # returns the first object fetched by SELECT * FROM people ORDER BY people.id LIMIT 1 # Person.where(["user_name = ?", user_name]).first # Person.where(["user_name = :u", { u: user_name }]).first # Person.order("created_on DESC").offset(5).first - # Person.first(3) # returns the first three objects fetched by SELECT * FROM people LIMIT 3 - # - # ==== Rails 3 - # - # Person.first # SELECT "people".* FROM "people" LIMIT 1 - # - # NOTE: Rails 3 may not order this query by the primary key and the order - # will depend on the database implementation. In order to ensure that behavior, - # use <tt>User.order(:id).first</tt> instead. - # - # ==== Rails 4 - # - # Person.first # SELECT "people".* FROM "people" ORDER BY "people"."id" ASC LIMIT 1 + # Person.first(3) # returns the first three objects fetched by SELECT * FROM people ORDER BY people.id LIMIT 3 # def first(limit = nil) if limit @@ -379,7 +367,7 @@ def construct_relation_for_association_calculations from = arel.froms.first if Arel::Table === from - apply_join_dependency(self, construct_join_dependency) + apply_join_dependency(self, construct_join_dependency(joins_values)) else # FIXME: as far as I can tell, `from` will always be an Arel::Table. # There are no tests that test this branch, but presumably it's diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/relation/predicate_builder.rb new/lib/active_record/relation/predicate_builder.rb --- old/lib/active_record/relation/predicate_builder.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/relation/predicate_builder.rb 2015-06-25 23:29:23.000000000 +0200 @@ -6,7 +6,9 @@ autoload :ArrayHandler, 'active_record/relation/predicate_builder/array_handler' def self.resolve_column_aliases(klass, hash) - hash = hash.dup + # This method is a hot spot, so for now, use Hash[] to dup the hash. + # https://bugs.ruby-lang.org/issues/7166 + hash = Hash[hash] hash.keys.grep(Symbol) do |key| if klass.attribute_alias? key hash[klass.attribute_alias(key)] = hash.delete key @@ -112,7 +114,8 @@ @handlers.unshift([klass, handler]) end - register_handler(BasicObject, ->(attribute, value) { attribute.eq(value) }) + BASIC_OBJECT_HANDLER = ->(attribute, value) { attribute.eq(value) } # :nodoc: + register_handler(BasicObject, BASIC_OBJECT_HANDLER) # FIXME: I think we need to deprecate this behavior register_handler(Class, ->(attribute, value) { attribute.eq(value.name) }) register_handler(Base, ->(attribute, value) { attribute.eq(value.id) }) @@ -142,5 +145,11 @@ value end end + + def self.can_be_bound?(value) # :nodoc: + !value.nil? && + !value.is_a?(Hash) && + handler_for(value) == BASIC_OBJECT_HANDLER + end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/relation/query_methods.rb new/lib/active_record/relation/query_methods.rb --- old/lib/active_record/relation/query_methods.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/relation/query_methods.rb 2015-06-25 23:29:23.000000000 +0200 @@ -909,7 +909,7 @@ where_values.reject! do |rel| case rel - when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThanOrEqual + when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual subrelation = (rel.left.kind_of?(Arel::Attributes::Attribute) ? rel.left : rel.right) subrelation.name == target_value end @@ -965,12 +965,9 @@ def create_binds(opts) bindable, non_binds = opts.partition do |column, value| - case value - when String, Integer, ActiveRecord::StatementCache::Substitute - @klass.columns_hash.include? column.to_s - else - false - end + PredicateBuilder.can_be_bound?(value) && + @klass.columns_hash.include?(column.to_s) && + !@klass.reflect_on_aggregation(column) end association_binds, non_binds = non_binds.partition do |column, value| @@ -980,6 +977,8 @@ new_opts = {} binds = [] + connection = self.connection + bindable.each do |(column,value)| binds.push [@klass.columns_hash[column.to_s], value] new_opts[column] = connection.substitute_at(column) @@ -1064,15 +1063,13 @@ end def arel_columns(columns) - if from_value - columns - else - columns.map do |field| - if (Symbol === field || String === field) && columns_hash.key?(field.to_s) - arel_table[field] - else - field - end + columns.map do |field| + if (Symbol === field || String === field) && columns_hash.key?(field.to_s) && !from_value + arel_table[field] + elsif Symbol === field + connection.quote_table_name(field.to_s) + else + field end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/tasks/database_tasks.rb new/lib/active_record/tasks/database_tasks.rb --- old/lib/active_record/tasks/database_tasks.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/tasks/database_tasks.rb 2015-06-25 23:29:23.000000000 +0200 @@ -197,7 +197,7 @@ load_schema_current(format, file) end - def schema_file(format = ActiveSupport::Base.schema_format) + def schema_file(format = ActiveRecord::Base.schema_format) case format when :ruby File.join(db_dir, "schema.rb") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/transactions.rb new/lib/active_record/transactions.rb --- old/lib/active_record/transactions.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/transactions.rb 2015-06-25 23:29:23.000000000 +0200 @@ -311,7 +311,7 @@ # Ensure that it is not called if the object was never persisted (failed create), # but call it after the commit of a destroyed object. def committed!(should_run_callbacks = true) #:nodoc: - _run_commit_callbacks if should_run_callbacks && destroyed? || persisted? + run_callbacks(:commit) if should_run_callbacks && destroyed? || persisted? ensure force_clear_transaction_record_state end @@ -319,7 +319,7 @@ # Call the +after_rollback+ callbacks. The +force_restore_state+ argument indicates if the record # 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: - _run_rollback_callbacks if should_run_callbacks + run_callbacks(:rollback) if should_run_callbacks ensure restore_transaction_record_state(force_restore_state) clear_transaction_record_state @@ -328,9 +328,13 @@ # Add the record to the current transaction so that the +after_rollback+ and +after_commit+ callbacks # can be called. def add_to_transaction - if self.class.connection.add_transaction_record(self) - remember_transaction_record_state + if has_transactional_callbacks? + self.class.connection.add_transaction_record(self) + else + sync_with_transaction_state + set_transaction_state(self.class.connection.transaction_state) end + remember_transaction_record_state end # Executes +method+ within a transaction and captures its return value as a @@ -385,10 +389,14 @@ transaction_level = (@_start_transaction_state[:level] || 0) - 1 if transaction_level < 1 || force restore_state = @_start_transaction_state - thaw unless restore_state[:frozen?] + thaw @new_record = restore_state[:new_record] @destroyed = restore_state[:destroyed] - write_attribute(self.class.primary_key, restore_state[:id]) if self.class.primary_key + pk = self.class.primary_key + if pk && read_attribute(pk) != restore_state[:id] + write_attribute(pk, restore_state[:id]) + end + freeze if restore_state[:frozen?] end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/type/boolean.rb new/lib/active_record/type/boolean.rb --- old/lib/active_record/type/boolean.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/type/boolean.rb 2015-06-25 23:29:23.000000000 +0200 @@ -16,6 +16,7 @@ if !ConnectionAdapters::Column::FALSE_VALUES.include?(value) ActiveSupport::Deprecation.warn(<<-MSG.squish) You attempted to assign a value which is not explicitly `true` or `false` + (#{value.inspect}) to a boolean column. Currently this value casts to `false`. This will change to match Ruby's semantics, and will cast to `true` in Rails 5. If you would like to maintain the current behavior, you should diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/type/hash_lookup_type_map.rb new/lib/active_record/type/hash_lookup_type_map.rb --- old/lib/active_record/type/hash_lookup_type_map.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/type/hash_lookup_type_map.rb 2015-06-25 23:29:23.000000000 +0200 @@ -1,12 +1,18 @@ module ActiveRecord module Type class HashLookupTypeMap < TypeMap # :nodoc: - delegate :key?, to: :@mapping - def alias_type(type, alias_type) register_type(type) { |_, *args| lookup(alias_type, *args) } end + def key?(key) + @mapping.key?(key) + end + + def keys + @mapping.keys + end + private def perform_fetch(type, *args, &block) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/type/serialized.rb new/lib/active_record/type/serialized.rb --- old/lib/active_record/type/serialized.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/type/serialized.rb 2015-06-25 23:29:23.000000000 +0200 @@ -27,9 +27,15 @@ end end + def inspect + Kernel.instance_method(:inspect).bind(self).call + end + def changed_in_place?(raw_old_value, value) return false if value.nil? - subtype.changed_in_place?(raw_old_value, type_cast_for_database(value)) + raw_new_value = type_cast_for_database(value) + raw_old_value.nil? != raw_new_value.nil? || + subtype.changed_in_place?(raw_old_value, raw_new_value) end def accessor diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/validations/uniqueness.rb new/lib/active_record/validations/uniqueness.rb --- old/lib/active_record/validations/uniqueness.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record/validations/uniqueness.rb 2015-06-25 23:29:23.000000000 +0200 @@ -15,11 +15,15 @@ table = finder_class.arel_table value = map_enum_attribute(finder_class, attribute, value) - relation = build_relation(finder_class, table, attribute, value) - relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) if record.persisted? - relation = scope_relation(record, table, relation) - relation = finder_class.unscoped.where(relation) - relation = relation.merge(options[:conditions]) if options[:conditions] + begin + relation = build_relation(finder_class, table, attribute, value) + relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) if record.persisted? + relation = scope_relation(record, table, relation) + relation = finder_class.unscoped.where(relation) + relation = relation.merge(options[:conditions]) if options[:conditions] + rescue RangeError + relation = finder_class.none + end if relation.exists? error_options = options.except(:case_sensitive, :scope, :conditions) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record.rb new/lib/active_record.rb --- old/lib/active_record.rb 2015-03-19 17:40:46.000000000 +0100 +++ new/lib/active_record.rb 2015-06-25 23:29:22.000000000 +0200 @@ -52,6 +52,7 @@ autoload :QueryCache autoload :Querying autoload :ReadonlyAttributes + autoload :RecordInvalid, 'active_record/validations' autoload :Reflection autoload :RuntimeRegistry autoload :Sanitization diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2015-03-19 17:40:46.000000000 +0100 +++ new/metadata 2015-06-25 23:29:22.000000000 +0200 @@ -1,14 +1,14 @@ --- !ruby/object:Gem::Specification name: activerecord version: !ruby/object:Gem::Version - version: 4.2.1 + version: 4.2.3 platform: ruby authors: - David Heinemeier Hansson autorequire: bindir: bin cert_chain: [] -date: 2015-03-19 00:00:00.000000000 Z +date: 2015-06-25 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: activesupport @@ -16,28 +16,28 @@ requirements: - - '=' - !ruby/object:Gem::Version - version: 4.2.1 + version: 4.2.3 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '=' - !ruby/object:Gem::Version - version: 4.2.1 + version: 4.2.3 - !ruby/object:Gem::Dependency name: activemodel requirement: !ruby/object:Gem::Requirement requirements: - - '=' - !ruby/object:Gem::Version - version: 4.2.1 + version: 4.2.3 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '=' - !ruby/object:Gem::Version - version: 4.2.1 + version: 4.2.3 - !ruby/object:Gem::Dependency name: arel requirement: !ruby/object:Gem::Requirement