[DRE-commits] [ruby-activerecord-3.2] 01/05: New upstream version 3.2.16
Ondrej Sury
ondrej at moszumanska.debian.org
Sun Dec 15 15:36:54 UTC 2013
This is an automated email from the git hooks/post-receive script.
ondrej pushed a commit to branch master
in repository ruby-activerecord-3.2.
commit 39f9986632b553fb05a876383afd11de8c1577e4
Author: Ondřej Surý <ondrej at sury.org>
Date: Wed Dec 4 17:35:32 2013 +0100
New upstream version 3.2.16
---
CHANGELOG.md | 191 ++++++++++++++++++++-
checksums.yaml.gz | Bin 265 -> 269 bytes
lib/active_record/associations/association.rb | 12 +-
.../associations/belongs_to_association.rb | 2 +-
.../belongs_to_polymorphic_association.rb | 3 +-
.../associations/builder/belongs_to.rb | 5 +-
.../associations/collection_association.rb | 2 +-
lib/active_record/associations/collection_proxy.rb | 10 +-
.../associations/has_many_association.rb | 4 +-
lib/active_record/associations/join_dependency.rb | 2 +-
.../join_dependency/join_association.rb | 7 +-
.../associations/preloader/through_association.rb | 3 +-
.../associations/through_association.rb | 2 +-
lib/active_record/autosave_association.rb | 17 +-
.../abstract/schema_definitions.rb | 4 +-
.../connection_adapters/mysql2_adapter.rb | 8 +-
.../connection_adapters/postgresql_adapter.rb | 12 +-
.../connection_adapters/schema_cache.rb | 4 +-
lib/active_record/explain_subscriber.rb | 2 +-
lib/active_record/fixtures.rb | 4 +-
lib/active_record/locking/optimistic.rb | 2 +-
lib/active_record/model_schema.rb | 6 +-
lib/active_record/nested_attributes.rb | 58 +++++--
lib/active_record/railtie.rb | 13 +-
lib/active_record/railties/databases.rake | 3 +-
lib/active_record/relation/calculations.rb | 11 +-
lib/active_record/relation/finder_methods.rb | 5 +-
lib/active_record/relation/spawn_methods.rb | 42 ++++-
lib/active_record/store.rb | 2 +-
lib/active_record/version.rb | 2 +-
metadata.yml | 29 ++--
31 files changed, 367 insertions(+), 100 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec017f8..878e5ee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,188 @@
-## Rails 3.2.13 (Feb 17, 2013) ##
+## Rails 3.2.15 (Oct 16, 2013) ##
+
+* When calling the method .find_or_initialize_by_* from a collection_proxy
+ it should set the inverse_of relation even when the entry was found on the db.
+
+ *arthurnn*
+
+* Callbacks on has_many should access the in memory parent if a inverse_of is set.
+
+ *arthurnn*
+
+* Fix `FinderMethods#last` unscoped primary key.
+
+ Fixes #11917.
+
+ *Eugene Kalenkovich*
+
+* Load fixtures from linked folders.
+
+ *Kassio Borges*
+
+* When using optimistic locking, `update` was not passing the column to `quote_value`
+ to allow the connection adapter to properly determine how to quote the value. This was
+ affecting certain databases that use specific colmn types.
+
+ Fixes: #6763
+
+ *Alfred Wong*
+
+
+## Rails 3.2.14 (Jul 22, 2013) ##
+
+* Fix merge error when Equality LHS is non-attribute.
+ Backport of #7380.
+
+ *Karmes Alexander*
+
+* Do not re-create destroyed association when saving the parent object.
+
+ Fixes #11450.
+
+ *Paul Nikitochkin*
+
+* Do not shallow the original exception in `exec_cache` on PostgreSQL adapter.
+
+ Fixes #11260.
+
+ *Rafael Mendonça França*
+
+* Fix `ActiveRecord::Store` incorrectly tracking changes of its attributes.
+ Fixes #10373.
+
+ *Janko Marohnić*
+
+* Fix a bug that prevented the use of the default STI inheritance column
+ (ActiveRecord::Base.inheritance_column = 'some_column'.)
+
+ *chapmajs + Takehiro Adachi*
+
+* Fix mysql2 adapter raises the correct exception when executing a query on a
+ closed connection.
+
+ *Yves Senn*
+
+* Fixes bug where `Company.new.contract_ids` would incorrectly load
+ all non-associated contracts.
+
+ Example:
+
+ company = Company.new # Company has many :contracts
+
+ # before
+ company.contract_ids # => SELECT ... WHERE `contracts`.`company_id` IS NULL
+
+ # after
+ company.contract_ids # => []
+
+ *Jared Armstrong*
+
+* Fix the `:primary_key` option for `has_many` associations.
+ Fixes #10693.
+
+ *Yves Senn*
+
+* fixes bug introduced by #3329. Now, when autosaving associations,
+ deletions happen before inserts and saves. This prevents a 'duplicate
+ unique value' database error that would occur if a record being created had
+ the same value on a unique indexed field as that of a record being destroyed.
+
+ Backport of #10417
+
+ *Johnny Holton*
+
+* Fix that under some conditions, Active Record could produce invalid SQL of the sort:
+ "SELECT DISTINCT DISTINCT".
+
+ Backport of #6792.
+
+ *Ben Woosley*
+
+* Require `ActiveRecord::Base` in railtie hooks for rake_tasks, console and runner to
+ avoid circular constant loading issues.
+
+ Backport #7695.
+
+ Fixes #7683 and #882
+
+ *Ben Holley*
+
+* Maintain context for joins within ActiveRecord::Relation merges.
+ Backport #10164.
+
+ *Neeraj Singh + Andrew Horner*
+
+* Make sure the `EXPLAIN` command is never triggered by a `select_db` call.
+
+ *Daniel Schierbeck*
+
+* Revert changes on `pluck` that was ignoring the select clause when the relation already
+ has one. This caused a regression since it changed the behavior in a stable release.
+
+ Fixes #9777.
+
+ *Rafael Mendonça França*
+
+* Confirm a record has not already been destroyed before decrementing counter cache.
+
+ *Ben Tucker*
+
+* Default values for PostgreSQL bigint types now get parsed and dumped to the
+ schema correctly.
+ Backport #10098.
+
+ *Erik Peterson*
+
+* Removed warning when `auto_explain_threshold_in_seconds` is set and the
+ connection adapter doesn't support explain.
+ This is causing a regression since the Active Record Railtie is trying to
+ connect to the development database in the application boot.
+
+ *Rafael Mendonça França*
+
+* Do not reset `inheritance_column` when it's set explicitly.
+ Backport of #5327.
+
+ *kennyj + Fred Wu*
+
+* Fix a problem wrong exception is occured
+ when raising no translatable exception in PostgreSQL.
+
+ *kennyj*
+
+* Resets the postgres search path in the structure.sql after the structure
+ is dumped in order to find schema_migrations table when multiples schemas
+ are used.
+ Fixes #9796.
+
+ *Juan M. Cuello + Dembskiy Alexander*
+
+* Reload the association target if it's stale. `@stale_state` should be nil
+ when a model isn't saved.
+ Fixes #7526.
+
+ *Larry Lv*
+
+* Don't read CSV files during execution of `db:fixtures:load`. CSV support for
+ fixtures was removed some time ago but the task was still loading them, even
+ though later the code was looking for the related yaml file instead.
+
+ *kennyj*
+
+
+## Rails 3.2.13 (Mar 18, 2013) ##
+
+* Chaining multiple preloaded scopes will correctly preload all the scopes
+ at the same time.
+
+ *Chris Geihsler*
* Reverted 921a296a3390192a71abeec6d9a035cc6d1865c8, 'Quote numeric values
compared to string columns.' This caused several regressions.
*Steve Klabnik*
-* Fix overriding of attributes by default_scope on `ActiveRecord::Base#dup`.
+* Fix overriding of attributes by `default_scope` on `ActiveRecord::Base#dup`.
*Hiroshige UMINO*
@@ -223,6 +400,16 @@
*Victor Costan*
+* `#pluck` can be used on a relation with `select` clause.
+ Fixes #7551.
+ Backport of #8176.
+
+ Example:
+
+ Topic.select([:approved, :id]).order(:id).pluck(:id)
+
+ *Yves Senn*
+
* Use `nil?` instead of `blank?` to check whether dynamic finder with a bang
should raise RecordNotFound.
Fixes #7238.
diff --git a/checksums.yaml.gz b/checksums.yaml.gz
index b8116f7..f10151f 100644
Binary files a/checksums.yaml.gz and b/checksums.yaml.gz differ
diff --git a/lib/active_record/associations/association.rb b/lib/active_record/associations/association.rb
index ab0d888..99f3079 100644
--- a/lib/active_record/associations/association.rb
+++ b/lib/active_record/associations/association.rb
@@ -46,6 +46,7 @@ module ActiveRecord
@loaded = false
IdentityMap.remove(target) if IdentityMap.enabled? && target
@target = nil
+ @stale_state = nil
end
# Reloads the \target and returns +self+ on success.
@@ -128,16 +129,21 @@ module ActiveRecord
# This method is abstract in the sense that it relies on +find_target+,
# which is expected to be provided by descendants.
#
- # If the \target is already \loaded it is just returned. Thus, you can call
- # +load_target+ unconditionally to get the \target.
+ # If the \target is stale(the target no longer points to the record(s) that the
+ # relevant foreign_key(s) refers to.), force reload the \target.
+ #
+ # Otherwise if the \target is already \loaded it is just returned. Thus, you can
+ # call +load_target+ unconditionally to get the \target.
#
# ActiveRecord::RecordNotFound is rescued within the method, and it is
# not reraised. The proxy is \reset and +nil+ is the return value.
def load_target
- if find_target?
+ if (@stale_state && stale_target?) || find_target?
begin
if IdentityMap.enabled? && association_class && association_class.respond_to?(:base_class)
@target = IdentityMap.get(association_class, owner[reflection.foreign_key])
+ elsif @stale_state && stale_target?
+ @target = find_target
end
rescue NameError
nil
diff --git a/lib/active_record/associations/belongs_to_association.rb b/lib/active_record/associations/belongs_to_association.rb
index 97f531d..52c67df 100644
--- a/lib/active_record/associations/belongs_to_association.rb
+++ b/lib/active_record/associations/belongs_to_association.rb
@@ -72,7 +72,7 @@ module ActiveRecord
end
def stale_state
- owner[reflection.foreign_key].to_s
+ owner[reflection.foreign_key] && owner[reflection.foreign_key].to_s
end
end
end
diff --git a/lib/active_record/associations/belongs_to_polymorphic_association.rb b/lib/active_record/associations/belongs_to_polymorphic_association.rb
index 2ee5dbb..88ce03a 100644
--- a/lib/active_record/associations/belongs_to_polymorphic_association.rb
+++ b/lib/active_record/associations/belongs_to_polymorphic_association.rb
@@ -27,7 +27,8 @@ module ActiveRecord
end
def stale_state
- [super, owner[reflection.foreign_type].to_s]
+ foreign_key = super
+ foreign_key && [foreign_key.to_s, owner[reflection.foreign_type].to_s]
end
end
end
diff --git a/lib/active_record/associations/builder/belongs_to.rb b/lib/active_record/associations/builder/belongs_to.rb
index 1759a41..d787177 100644
--- a/lib/active_record/associations/builder/belongs_to.rb
+++ b/lib/active_record/associations/builder/belongs_to.rb
@@ -34,7 +34,10 @@ module ActiveRecord::Associations::Builder
method_name = "belongs_to_counter_cache_before_destroy_for_#{name}"
mixin.redefine_method(method_name) do
record = send(name)
- record.class.decrement_counter(cache_column, record.id) unless record.nil?
+
+ if record && !self.destroyed?
+ record.class.decrement_counter(cache_column, record.id)
+ end
end
model.before_destroy(method_name)
diff --git a/lib/active_record/associations/collection_association.rb b/lib/active_record/associations/collection_association.rb
index 65e8828..baddb98 100644
--- a/lib/active_record/associations/collection_association.rb
+++ b/lib/active_record/associations/collection_association.rb
@@ -43,7 +43,7 @@ module ActiveRecord
# Implements the ids reader method, e.g. foo.item_ids for Foo.has_many :items
def ids_reader
- if loaded? || options[:finder_sql]
+ if owner.new_record? || loaded? || options[:finder_sql]
load_target.map do |record|
record.send(reflection.association_primary_key)
end
diff --git a/lib/active_record/associations/collection_proxy.rb b/lib/active_record/associations/collection_proxy.rb
index 416a582..62cdb1e 100644
--- a/lib/active_record/associations/collection_proxy.rb
+++ b/lib/active_record/associations/collection_proxy.rb
@@ -77,10 +77,12 @@ module ActiveRecord
def method_missing(method, *args, &block)
match = DynamicFinderMatch.match(method)
if match && match.instantiator?
- send(:find_or_instantiator_by_attributes, match, match.attribute_names, *args) do |r|
- proxy_association.send :set_owner_attributes, r
- proxy_association.send :add_to_target, r
- yield(r) if block_given?
+ send(:find_or_instantiator_by_attributes, match, match.attribute_names, *args) do |record|
+ proxy_association.send :set_owner_attributes, record
+ proxy_association.send :add_to_target, record
+ yield(record) if block_given?
+ end.tap do |record|
+ proxy_association.send :set_inverse_instance, record
end
elsif target.respond_to?(method) || (!proxy_association.klass.respond_to?(method) && Class.respond_to?(method))
diff --git a/lib/active_record/associations/has_many_association.rb b/lib/active_record/associations/has_many_association.rb
index 059e6c7..290f814 100644
--- a/lib/active_record/associations/has_many_association.rb
+++ b/lib/active_record/associations/has_many_association.rb
@@ -9,6 +9,7 @@ module ActiveRecord
def insert_record(record, validate = true, raise = false)
set_owner_attributes(record)
+ set_inverse_instance(record)
if raise
record.save!(:validate => validate)
@@ -89,8 +90,7 @@ module ActiveRecord
records.each { |r| r.destroy }
update_counter(-records.length) unless inverse_updates_counter_cache?
else
- keys = records.map { |r| r[reflection.association_primary_key] }
- scope = scoped.where(reflection.association_primary_key => keys)
+ scope = self.scoped.where(reflection.klass.primary_key => records)
if method == :delete_all
update_counter(-scope.delete_all)
diff --git a/lib/active_record/associations/join_dependency.rb b/lib/active_record/associations/join_dependency.rb
index cd366ac..e3d8356 100644
--- a/lib/active_record/associations/join_dependency.rb
+++ b/lib/active_record/associations/join_dependency.rb
@@ -109,7 +109,7 @@ module ActiveRecord
case associations
when Symbol, String
reflection = parent.reflections[associations.to_s.intern] or
- raise ConfigurationError, "Association named '#{ associations }' was not found; perhaps you misspelled it?"
+ raise ConfigurationError, "Association named '#{ associations }' was not found on #{parent.active_record.name}; perhaps you misspelled it?"
unless join_association = find_join_association(reflection, parent)
@reflections << reflection
join_association = build_join_association(reflection, parent)
diff --git a/lib/active_record/associations/join_dependency/join_association.rb b/lib/active_record/associations/join_dependency/join_association.rb
index 03963ab..becf1a3 100644
--- a/lib/active_record/associations/join_dependency/join_association.rb
+++ b/lib/active_record/associations/join_dependency/join_association.rb
@@ -55,7 +55,12 @@ module ActiveRecord
def find_parent_in(other_join_dependency)
other_join_dependency.join_parts.detect do |join_part|
- parent == join_part
+ case parent
+ when JoinBase
+ parent.active_record == join_part.active_record
+ else
+ parent == join_part
+ end
end
end
diff --git a/lib/active_record/associations/preloader/through_association.rb b/lib/active_record/associations/preloader/through_association.rb
index 4cb7b56..e052b00 100644
--- a/lib/active_record/associations/preloader/through_association.rb
+++ b/lib/active_record/associations/preloader/through_association.rb
@@ -56,8 +56,7 @@ module ActiveRecord
through_options[:include] = options[:include] || options[:source]
through_options[:conditions] = options[:conditions]
end
-
- through_options[:order] = options[:order]
+ through_options[:order] = options[:order] if options.has_key?(:order)
end
through_options
diff --git a/lib/active_record/associations/through_association.rb b/lib/active_record/associations/through_association.rb
index fd0e90a..be890e5 100644
--- a/lib/active_record/associations/through_association.rb
+++ b/lib/active_record/associations/through_association.rb
@@ -62,7 +62,7 @@ module ActiveRecord
# properly support stale-checking for nested associations.
def stale_state
if through_reflection.macro == :belongs_to
- owner[through_reflection.foreign_key].to_s
+ owner[through_reflection.foreign_key] && owner[through_reflection.foreign_key].to_s
end
end
diff --git a/lib/active_record/autosave_association.rb b/lib/active_record/autosave_association.rb
index e1499fc..4da3929 100644
--- a/lib/active_record/autosave_association.rb
+++ b/lib/active_record/autosave_association.rb
@@ -332,16 +332,18 @@ module ActiveRecord
if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
begin
- records_to_destroy = []
+ if autosave
+ records_to_destroy = records.select(&:marked_for_destruction?)
+ records_to_destroy.each { |record| association.proxy.destroy(record) }
+ records -= records_to_destroy
+ end
records.each do |record|
next if record.destroyed?
saved = true
- if autosave && record.marked_for_destruction?
- records_to_destroy << record
- elsif autosave != false && (@new_record_before_save || record.new_record?)
+ if autosave != false && (@new_record_before_save || record.new_record?)
if autosave
saved = association.insert_record(record, false)
else
@@ -353,19 +355,14 @@ module ActiveRecord
raise ActiveRecord::Rollback unless saved
end
-
- records_to_destroy.each do |record|
- association.proxy.destroy(record)
- end
rescue
records.each {|x| IdentityMap.remove(x) } if IdentityMap.enabled?
raise
end
-
end
# reconstruct the scope now that we know the owner's id
- association.send(:reset_scope) if association.respond_to?(:reset_scope)
+ association.reset_scope if association.respond_to?(:reset_scope)
end
end
diff --git a/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index ddb6896..6a5cff6 100644
--- a/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -42,8 +42,8 @@ module ActiveRecord
# Represents the schema of an SQL table in an abstract way. This class
# provides methods for manipulating the schema representation.
#
- # Inside migration files, the +t+ object in +create_table+ and
- # +change_table+ is actually of this type:
+ # Inside migration files, the +t+ object in +create_table+
+ # is actually of this type:
#
# class SomeMigration < ActiveRecord::Migration
# def up
diff --git a/lib/active_record/connection_adapters/mysql2_adapter.rb b/lib/active_record/connection_adapters/mysql2_adapter.rb
index 524a7d3..c690b98 100644
--- a/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -204,9 +204,11 @@ module ActiveRecord
# Executes the SQL statement in the context of this connection.
def execute(sql, name = nil)
- # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
- # made since we established the connection
- @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
+ if @connection
+ # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
+ # made since we established the connection
+ @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
+ end
super
end
diff --git a/lib/active_record/connection_adapters/postgresql_adapter.rb b/lib/active_record/connection_adapters/postgresql_adapter.rb
index 8806693..e98337e 100644
--- a/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -142,7 +142,7 @@ module ActiveRecord
when NilClass
nil
# Numeric types
- when /\A\(?(-?\d+(\.\d*)?\)?)\z/
+ when /\A\(?(-?\d+(\.\d*)?\)?(::bigint)?)\z/
$1
# Character types
when /\A\(?'(.*)'::.*\b(?:character varying|bpchar|text)\z/m
@@ -1144,7 +1144,9 @@ module ActiveRecord
UNIQUE_VIOLATION = "23505"
def translate_exception(exception, message)
- case exception.result.error_field(PGresult::PG_DIAG_SQLSTATE)
+ return exception unless exception.respond_to?(:result)
+
+ case exception.result.try(:error_field, PGresult::PG_DIAG_SQLSTATE)
when UNIQUE_VIOLATION
RecordNotUnique.new(message, exception)
when FOREIGN_KEY_VIOLATION
@@ -1177,7 +1179,11 @@ module ActiveRecord
# prepared statements whose return value may have changed is
# FEATURE_NOT_SUPPORTED. Check here for more details:
# http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
- code = e.result.result_error_field(PGresult::PG_DIAG_SQLSTATE)
+ begin
+ code = e.result.result_error_field(PGresult::PG_DIAG_SQLSTATE)
+ rescue
+ raise e
+ end
if FEATURE_NOT_SUPPORTED == code
@statements.delete sql_key(sql)
retry
diff --git a/lib/active_record/connection_adapters/schema_cache.rb b/lib/active_record/connection_adapters/schema_cache.rb
index bc8d24a..9fc218d 100644
--- a/lib/active_record/connection_adapters/schema_cache.rb
+++ b/lib/active_record/connection_adapters/schema_cache.rb
@@ -9,7 +9,7 @@ module ActiveRecord
@tables = {}
@columns = Hash.new do |h, table_name|
- h[table_name] = conn.columns(table_name, "#{table_name} Columns")
+ h[table_name] = connection.columns(table_name, "#{table_name} Columns")
end
@columns_hash = Hash.new do |h, table_name|
@@ -19,7 +19,7 @@ module ActiveRecord
end
@primary_keys = Hash.new do |h, table_name|
- h[table_name] = table_exists?(table_name) ? conn.primary_key(table_name) : nil
+ h[table_name] = table_exists?(table_name) ? connection.primary_key(table_name) : nil
end
end
diff --git a/lib/active_record/explain_subscriber.rb b/lib/active_record/explain_subscriber.rb
index 859c8ed..1d861a5 100644
--- a/lib/active_record/explain_subscriber.rb
+++ b/lib/active_record/explain_subscriber.rb
@@ -15,7 +15,7 @@ module ActiveRecord
# 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)/i
+ EXPLAINED_SQLS = /\A\s*(select|update|delete|insert)\b/i
def ignore_payload?(payload)
payload[:exception] || IGNORED_PAYLOADS.include?(payload[:name]) || payload[:sql] !~ EXPLAINED_SQLS
end
diff --git a/lib/active_record/fixtures.rb b/lib/active_record/fixtures.rb
index 7a5634f..1e6b5c5 100644
--- a/lib/active_record/fixtures.rb
+++ b/lib/active_record/fixtures.rb
@@ -661,7 +661,7 @@ module ActiveRecord
end
def read_fixture_files
- yaml_files = Dir["#{@fixture_path}/**/*.yml"].select { |f|
+ yaml_files = Dir["#{@fixture_path}/{**,*}/*.yml"].select { |f|
::File.file?(f)
} + [yaml_file_path]
@@ -752,7 +752,7 @@ module ActiveRecord
def fixtures(*fixture_names)
if fixture_names.first == :all
- fixture_names = Dir["#{fixture_path}/**/*.{yml}"]
+ fixture_names = Dir["#{fixture_path}/{**,*}/*.{yml}"]
fixture_names.map! { |f| f[(fixture_path.size + 1)..-5] }
else
fixture_names = fixture_names.flatten.map { |n| n.to_s }
diff --git a/lib/active_record/locking/optimistic.rb b/lib/active_record/locking/optimistic.rb
index b288199..6265be8 100644
--- a/lib/active_record/locking/optimistic.rb
+++ b/lib/active_record/locking/optimistic.rb
@@ -80,7 +80,7 @@ module ActiveRecord
stmt = relation.where(
relation.table[self.class.primary_key].eq(id).and(
- relation.table[lock_col].eq(quote_value(previous_lock_value))
+ relation.table[lock_col].eq(quote_value(previous_lock_value, self.class.columns_hash[lock_col]))
)
).arel.compile_update(arel_attributes_values(false, false, attribute_names))
diff --git a/lib/active_record/model_schema.rb b/lib/active_record/model_schema.rb
index 1517e5e..40cc8dc 100644
--- a/lib/active_record/model_schema.rb
+++ b/lib/active_record/model_schema.rb
@@ -159,7 +159,7 @@ module ActiveRecord
# The name of the column containing the object's class when Single Table Inheritance is used
def inheritance_column
if self == Base
- 'type'
+ (@inheritance_column ||= nil) || 'type'
else
(@inheritance_column ||= nil) || superclass.inheritance_column
end
@@ -173,6 +173,7 @@ module ActiveRecord
def inheritance_column=(value)
@original_inheritance_column = inheritance_column
@inheritance_column = value.to_s
+ @explicit_inheritance_column = true
end
def set_inheritance_column(value = nil, &block) #:nodoc:
@@ -300,7 +301,8 @@ module ActiveRecord
connection.schema_cache.clear_table_cache!(table_name) if table_exists?
@column_names = @content_columns = @column_defaults = @columns = @columns_hash = nil
- @dynamic_methods_hash = @inheritance_column = nil
+ @dynamic_methods_hash = nil
+ @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
@arel_engine = @relation = nil
end
diff --git a/lib/active_record/nested_attributes.rb b/lib/active_record/nested_attributes.rb
index 0509165..41b62f6 100644
--- a/lib/active_record/nested_attributes.rb
+++ b/lib/active_record/nested_attributes.rb
@@ -92,8 +92,9 @@ module ActiveRecord
# accepts_nested_attributes_for :posts
# end
#
- # You can now set or update attributes on an associated post model through
- # the attribute hash.
+ # You can now set or update attributes on the associated posts through
+ # an attribute hash for a member: include the key +:posts_attributes+
+ # with an array of hashes of post attributes as a value.
#
# For each hash that does _not_ have an <tt>id</tt> key a new record will
# be instantiated, unless the hash also contains a <tt>_destroy</tt> key
@@ -116,10 +117,10 @@ module ActiveRecord
# hashes if they fail to pass your criteria. For example, the previous
# example could be rewritten as:
#
- # class Member < ActiveRecord::Base
- # has_many :posts
- # accepts_nested_attributes_for :posts, :reject_if => proc { |attributes| attributes['title'].blank? }
- # end
+ # class Member < ActiveRecord::Base
+ # has_many :posts
+ # accepts_nested_attributes_for :posts, :reject_if => proc { |attributes| attributes['title'].blank? }
+ # end
#
# params = { :member => {
# :name => 'joe', :posts_attributes => [
@@ -136,19 +137,19 @@ module ActiveRecord
#
# Alternatively, :reject_if also accepts a symbol for using methods:
#
- # class Member < ActiveRecord::Base
- # has_many :posts
- # accepts_nested_attributes_for :posts, :reject_if => :new_record?
- # end
+ # class Member < ActiveRecord::Base
+ # has_many :posts
+ # accepts_nested_attributes_for :posts, :reject_if => :new_record?
+ # end
#
- # class Member < ActiveRecord::Base
- # has_many :posts
- # accepts_nested_attributes_for :posts, :reject_if => :reject_posts
+ # class Member < ActiveRecord::Base
+ # has_many :posts
+ # accepts_nested_attributes_for :posts, :reject_if => :reject_posts
#
- # def reject_posts(attributed)
- # attributed['title'].blank?
- # end
- # end
+ # def reject_posts(attributed)
+ # attributed['title'].blank?
+ # end
+ # end
#
# If the hash contains an <tt>id</tt> key that matches an already
# associated record, the matching record will be modified:
@@ -185,6 +186,29 @@ module ActiveRecord
# member.save
# member.reload.posts.length # => 1
#
+ # Nested attributes for an associated collection can also be passed in
+ # the form of a hash of hashes instead of an array of hashes:
+ #
+ # Member.create(:name => 'joe',
+ # :posts_attributes => { :first => { :title => 'Foo' },
+ # :second => { :title => 'Bar' } })
+ #
+ # has the same effect as
+ #
+ # Member.create(:name => 'joe',
+ # :posts_attributes => [ { :title => 'Foo' },
+ # { :title => 'Bar' } ])
+ #
+ # The keys of the hash which is the value for +:posts_attributes+ are
+ # ignored in this case.
+ # However, it is not allowed to use +'id'+ or +:id+ for one of
+ # such keys, otherwise the hash will be wrapped in an array and
+ # interpreted as an attribute hash for a single post.
+ #
+ # Passing attributes for an associated collection in the form of a hash
+ # of hashes can be used with hashes generated from HTTP/HTML parameters,
+ # where there maybe no natural way to submit an array of hashes.
+ #
# === Saving
#
# All changes to models, including the destruction of those marked for
diff --git a/lib/active_record/railtie.rb b/lib/active_record/railtie.rb
index 055d27d..4e39654 100644
--- a/lib/active_record/railtie.rb
+++ b/lib/active_record/railtie.rb
@@ -30,6 +30,7 @@ module ActiveRecord
)
rake_tasks do
+ require "active_record/base"
load "active_record/railties/databases.rake"
end
@@ -38,9 +39,14 @@ module ActiveRecord
# first time. Also, make it output to STDERR.
console do |app|
require "active_record/railties/console_sandbox" if app.sandbox?
+ require "active_record/base"
ActiveRecord::Base.logger = Logger.new(STDERR)
end
+ runner do |app|
+ require "active_record/base"
+ end
+
initializer "active_record.initialize_timezone" do
ActiveSupport.on_load(:active_record) do
self.time_zone_aware_attributes = true
@@ -83,13 +89,6 @@ module ActiveRecord
end
end
- initializer "active_record.validate_explain_support" do |app|
- if app.config.active_record[:auto_explain_threshold_in_seconds] &&
- !ActiveRecord::Base.connection.supports_explain?
- warn "auto_explain_threshold_in_seconds is set but will be ignored because your adapter does not support this feature. Please unset the configuration to avoid this warning."
- end
- end
-
# Expose database runtime to controller for logging.
initializer "active_record.log_runtime" do |app|
require "active_record/railties/controller_runtime"
diff --git a/lib/active_record/railties/databases.rake b/lib/active_record/railties/databases.rake
index 8f7c7f6..b8aed49 100644
--- a/lib/active_record/railties/databases.rake
+++ b/lib/active_record/railties/databases.rake
@@ -355,7 +355,7 @@ db_namespace = namespace :db do
base_dir = File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
- (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir["#{fixtures_dir}/**/*.{yml,csv}"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
ActiveRecord::Fixtures.create_fixtures(fixtures_dir, fixture_file)
end
end
@@ -427,6 +427,7 @@ db_namespace = namespace :db do
end
`pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(config['database'])}`
raise 'Error dumping database' if $?.exitstatus == 1
+ File.open(filename, "a") { |f| f << "SET search_path TO #{ActiveRecord::Base.connection.schema_search_path};\n\n" }
when /sqlite/
dbfile = config['database']
`sqlite3 #{dbfile} .schema > #{filename}`
diff --git a/lib/active_record/relation/calculations.rb b/lib/active_record/relation/calculations.rb
index 1f9dbdc..afab793 100644
--- a/lib/active_record/relation/calculations.rb
+++ b/lib/active_record/relation/calculations.rb
@@ -179,14 +179,13 @@ module ActiveRecord
def pluck(column_name)
if column_name.is_a?(Symbol) && column_names.include?(column_name.to_s)
column_name = "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}"
- else
- column_name = column_name.to_s
end
- relation = clone
- relation.select_values = [column_name]
- klass.connection.select_all(relation.arel).map! do |attributes|
- klass.type_cast_attribute(attributes.keys.first, klass.initialize_attributes(attributes))
+ result = klass.connection.exec_query(select(column_name).to_sql)
+ last_column = result.columns.last
+
+ result.map do |attributes|
+ klass.type_cast_attribute(last_column, klass.initialize_attributes(attributes))
end
end
diff --git a/lib/active_record/relation/finder_methods.rb b/lib/active_record/relation/finder_methods.rb
index 08cfe4f..1efe4db 100644
--- a/lib/active_record/relation/finder_methods.rb
+++ b/lib/active_record/relation/finder_methods.rb
@@ -134,8 +134,8 @@ module ActiveRecord
def last(*args)
if args.any?
if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash))
- if order_values.empty?
- order("#{primary_key} DESC").limit(*args).reverse
+ if order_values.empty? && primary_key
+ order("#{quoted_table_name}.#{quoted_primary_key} DESC").limit(*args).reverse
else
to_a.last(*args)
end
@@ -254,6 +254,7 @@ module ActiveRecord
values = @klass.connection.distinct("#{@klass.connection.quote_table_name table_name}.#{primary_key}", orders)
relation = relation.dup.select(values)
+ relation.uniq_value = nil
id_rows = @klass.connection.select_all(relation.arel, 'SQL', relation.bind_values)
ids_array = id_rows.map {|row| row[primary_key]}
diff --git a/lib/active_record/relation/spawn_methods.rb b/lib/active_record/relation/spawn_methods.rb
index c25570d..93fa30e 100644
--- a/lib/active_record/relation/spawn_methods.rb
+++ b/lib/active_record/relation/spawn_methods.rb
@@ -17,26 +17,27 @@ module ActiveRecord
if method == :includes
merged_relation = merged_relation.includes(value)
else
- merged_relation.send(:"#{method}_values=", value)
+ merge_relation_method(merged_relation, method, value)
end
end
end
(Relation::MULTI_VALUE_METHODS - [:joins, :where, :order]).each do |method|
value = r.send(:"#{method}_values")
- merged_relation.send(:"#{method}_values=", merged_relation.send(:"#{method}_values") + value) if value.present?
+ merge_relation_method(merged_relation, method, value) if value.present?
end
- merged_relation.joins_values += r.joins_values
+ merge_joins(merged_relation, r)
merged_wheres = @where_values + r.where_values
unless @where_values.empty?
- # Remove duplicates, last one wins.
+ # Remove duplicate ARel attributes. Last one wins.
seen = Hash.new { |h,table| h[table] = {} }
merged_wheres = merged_wheres.reverse.reject { |w|
nuke = false
- if w.respond_to?(:operator) && w.operator == :==
+ if w.respond_to?(:operator) && w.operator == :== &&
+ w.left.respond_to?(:relation)
name = w.left.name
table = w.left.relation.name
nuke = seen[table][name]
@@ -144,5 +145,36 @@ module ActiveRecord
relation
end
+ private
+
+ def merge_joins(relation, other)
+ values = other.joins_values
+ return if values.blank?
+
+ if other.klass >= relation.klass
+ relation.joins_values += values
+ else
+ joins_dependency, rest = values.partition do |join|
+ case join
+ when Hash, Symbol, Array
+ true
+ else
+ false
+ end
+ end
+
+ join_dependency = ActiveRecord::Associations::JoinDependency.new(
+ other.klass,
+ joins_dependency,
+ []
+ )
+
+ relation.joins_values += join_dependency.join_associations + rest
+ end
+ end
+
+ def merge_relation_method(relation, method, value)
+ relation.send(:"#{method}_values=", relation.send(:"#{method}_values") + value)
+ end
end
end
diff --git a/lib/active_record/store.rb b/lib/active_record/store.rb
index 49d01de..bacb78e 100644
--- a/lib/active_record/store.rb
+++ b/lib/active_record/store.rb
@@ -37,8 +37,8 @@ module ActiveRecord
Array(keys).flatten.each do |key|
define_method("#{key}=") do |value|
send("#{store_attribute}=", {}) unless send(store_attribute).is_a?(Hash)
- send(store_attribute)[key] = value
send("#{store_attribute}_will_change!")
+ send(store_attribute)[key] = value
end
define_method(key) do
diff --git a/lib/active_record/version.rb b/lib/active_record/version.rb
index 9069d99..1210df3 100644
--- a/lib/active_record/version.rb
+++ b/lib/active_record/version.rb
@@ -2,7 +2,7 @@ module ActiveRecord
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 13
+ TINY = 16
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
diff --git a/metadata.yml b/metadata.yml
index 336bf0c..8f3eb1d 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,14 +1,14 @@
--- !ruby/object:Gem::Specification
name: activerecord
version: !ruby/object:Gem::Version
- version: 3.2.13
+ version: 3.2.16
platform: ruby
authors:
- David Heinemeier Hansson
autorequire:
bindir: bin
cert_chain: []
-date: 2013-03-18 00:00:00.000000000 Z
+date: 2013-12-03 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
name: activesupport
@@ -16,54 +16,54 @@ dependencies:
requirements:
- - '='
- !ruby/object:Gem::Version
- version: 3.2.13
+ version: 3.2.16
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - '='
- !ruby/object:Gem::Version
- version: 3.2.13
+ version: 3.2.16
- !ruby/object:Gem::Dependency
name: activemodel
requirement: !ruby/object:Gem::Requirement
requirements:
- - '='
- !ruby/object:Gem::Version
- version: 3.2.13
+ version: 3.2.16
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - '='
- !ruby/object:Gem::Version
- version: 3.2.13
+ version: 3.2.16
- !ruby/object:Gem::Dependency
name: arel
requirement: !ruby/object:Gem::Requirement
requirements:
- - - ~>
+ - - "~>"
- !ruby/object:Gem::Version
version: 3.0.2
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - - ~>
+ - - "~>"
- !ruby/object:Gem::Version
version: 3.0.2
- !ruby/object:Gem::Dependency
name: tzinfo
requirement: !ruby/object:Gem::Requirement
requirements:
- - - ~>
+ - - "~>"
- !ruby/object:Gem::Version
version: 0.3.29
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - - ~>
+ - - "~>"
- !ruby/object:Gem::Version
version: 0.3.29
description: Databases on Rails. Build a persistent domain model by mapping database
@@ -225,22 +225,23 @@ files:
- lib/rails/generators/active_record/session_migration/templates/migration.rb
- lib/rails/generators/active_record.rb
homepage: http://www.rubyonrails.org
-licenses: []
+licenses:
+- MIT
metadata: {}
post_install_message:
rdoc_options:
-- --main
+- "--main"
- README.rdoc
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
requirements:
- - - '>='
+ - - ">="
- !ruby/object:Gem::Version
version: 1.8.7
required_rubygems_version: !ruby/object:Gem::Requirement
requirements:
- - - '>='
+ - - ">="
- !ruby/object:Gem::Version
version: '0'
requirements: []
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-activerecord-3.2.git
More information about the Pkg-ruby-extras-commits
mailing list