aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/associations/alias_tracker.rb15
-rw-r--r--activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb2
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb24
-rw-r--r--activerecord/lib/active_record/associations/join_dependency.rb2
-rw-r--r--activerecord/lib/active_record/associations/preloader/association.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb3
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/connection_specification.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb22
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb13
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb2
-rw-r--r--activerecord/lib/active_record/fixtures.rb4
-rw-r--r--activerecord/lib/active_record/migration.rb13
-rw-r--r--activerecord/lib/active_record/railtie.rb2
-rw-r--r--activerecord/lib/active_record/railties/databases.rake10
-rw-r--r--activerecord/lib/active_record/reflection.rb2
-rw-r--r--activerecord/lib/active_record/relation.rb10
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb13
-rw-r--r--activerecord/lib/active_record/type/integer.rb2
-rw-r--r--activerecord/lib/active_record/type/type_map.rb10
25 files changed, 118 insertions, 82 deletions
diff --git a/activerecord/lib/active_record/associations/alias_tracker.rb b/activerecord/lib/active_record/associations/alias_tracker.rb
index a6a1947148..0c3234ed24 100644
--- a/activerecord/lib/active_record/associations/alias_tracker.rb
+++ b/activerecord/lib/active_record/associations/alias_tracker.rb
@@ -57,20 +57,10 @@ module ActiveRecord
end
def aliased_table_for(table_name, aliased_name)
- table_alias = aliased_name_for(table_name, aliased_name)
-
- if table_alias == table_name
- Arel::Table.new(table_name)
- else
- Arel::Table.new(table_name).alias(table_alias)
- end
- end
-
- def aliased_name_for(table_name, aliased_name)
if aliases[table_name].zero?
# If it's zero, we can have our table_name
aliases[table_name] = 1
- table_name
+ Arel::Table.new(table_name)
else
# Otherwise, we need to use an alias
aliased_name = connection.table_alias_for(aliased_name)
@@ -78,11 +68,12 @@ module ActiveRecord
# Update the count
aliases[aliased_name] += 1
- if aliases[aliased_name] > 1
+ table_alias = if aliases[aliased_name] > 1
"#{truncate(aliased_name)}_#{aliases[aliased_name]}"
else
aliased_name
end
+ Arel::Table.new(table_name).alias(table_alias)
end
end
diff --git a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
index 357b28ac94..092b4ebd2f 100644
--- a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
+++ b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
@@ -110,7 +110,7 @@ module ActiveRecord::Associations::Builder
rhs_options = {}
if options.key? :class_name
- rhs_options[:foreign_key] = options[:class_name].foreign_key
+ rhs_options[:foreign_key] = options[:class_name].to_s.foreign_key
rhs_options[:class_name] = options[:class_name]
end
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 93f611dd8d..2b7d39893d 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -175,8 +175,8 @@ module ActiveRecord
end
# Removes all records from the association without calling callbacks
- # on the associated records. It honors the `:dependent` option. However
- # if the `:dependent` value is `:destroy` then in that case the `:delete_all`
+ # on the associated records. It honors the +:dependent+ option. However
+ # if the +:dependent+ value is +:destroy+ then in that case the +:delete_all+
# deletion strategy for the association is applied.
#
# You can force a particular deletion strategy by passing a parameter.
@@ -358,6 +358,7 @@ module ActiveRecord
if owner.new_record?
replace_records(other_array, original_target)
else
+ replace_common_records_in_memory(other_array, original_target)
if other_array != original_target
transaction { replace_records(other_array, original_target) }
end
@@ -385,11 +386,18 @@ module ActiveRecord
target
end
- def add_to_target(record, skip_callbacks = false)
+ def add_to_target(record, skip_callbacks = false, &block)
+ if association_scope.distinct_value
+ index = @target.index(record)
+ end
+ replace_on_target(record, index, skip_callbacks, &block)
+ end
+
+ def replace_on_target(record, index, skip_callbacks)
callback(:before_add, record) unless skip_callbacks
yield(record) if block_given?
- if association_scope.distinct_value && index = @target.index(record)
+ if index
@target[index] = record
else
@target << record
@@ -534,6 +542,14 @@ module ActiveRecord
target
end
+ def replace_common_records_in_memory(new_target, original_target)
+ common_records = new_target & original_target
+ common_records.each do |record|
+ skip_callbacks = true
+ replace_on_target(record, @target.index(record), skip_callbacks)
+ end
+ end
+
def concat_records(records, should_raise = false)
result = true
diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb
index c5c4edd090..285d0ec9af 100644
--- a/activerecord/lib/active_record/associations/join_dependency.rb
+++ b/activerecord/lib/active_record/associations/join_dependency.rb
@@ -94,7 +94,7 @@ module ActiveRecord
#
def initialize(base, associations, joins)
@alias_tracker = AliasTracker.create(base.connection, joins)
- @alias_tracker.aliased_name_for(base.table_name, base.table_name) # Updates the count for base.table_name to 1
+ @alias_tracker.aliased_table_for(base.table_name, base.table_name) # Updates the count for base.table_name to 1
tree = self.class.make_tree associations
@join_root = JoinBase.new base, build(tree, base)
@join_root.children.each { |child| construct_tables! @join_root, child }
diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb
index 496c426986..7d6523dbc4 100644
--- a/activerecord/lib/active_record/associations/preloader/association.rb
+++ b/activerecord/lib/active_record/associations/preloader/association.rb
@@ -142,14 +142,8 @@ module ActiveRecord
scope._select! preload_values[:select] || values[:select] || table[Arel.star]
scope.includes! preload_values[:includes] || values[:includes]
-
- if preload_values.key? :order
- scope.order! preload_values[:order]
- else
- if values.key? :order
- scope.order! values[:order]
- end
- end
+ scope.joins! preload_values[:joins] || values[:joins]
+ scope.order! preload_values[:order] || values[:order]
if preload_values[:readonly] || values[:readonly]
scope.readonly!
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index 5c4c214385..d2236d046b 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -226,7 +226,7 @@ module ActiveRecord
# t.integer :shop_id, :creator_id
# t.string :item_number, index: true
# t.string :name, :value, default: "Untitled"
- # t.timestamps
+ # t.timestamps null: false
# end
#
# There's a short-hand method for each of the type values declared at the top. And then there's
@@ -287,7 +287,9 @@ module ActiveRecord
end
# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
- # <tt>:updated_at</tt> to the table.
+ # <tt>:updated_at</tt> to the table. See SchemaStatements#add_timestamps
+ #
+ # t.timestamps null: false
def timestamps(*args)
options = args.extract_options!
emit_warning_if_null_unspecified(options)
@@ -412,8 +414,6 @@ module ActiveRecord
# end
#
class Table
- include TimestampDefaultDeprecation
-
attr_reader :name
def initialize(table_name, base)
@@ -462,9 +462,8 @@ module ActiveRecord
# Adds timestamps (+created_at+ and +updated_at+) columns to the table. See SchemaStatements#add_timestamps
#
- # t.timestamps
+ # t.timestamps null: false
def timestamps(options = {})
- emit_warning_if_null_unspecified(options)
@base.add_timestamps(name, options)
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index cc86c3776e..99fa9b7d29 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -571,6 +571,9 @@ module ActiveRecord
# rename_index :people, 'index_people_on_last_name', 'index_users_on_last_name'
#
def rename_index(table_name, old_name, new_name)
+ if new_name.length > allowed_index_name_length
+ raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{allowed_index_name_length} characters"
+ end
# this is a naive implementation; some DBs may support this more efficiently (Postgres, for instance)
old_index_def = indexes(table_name).detect { |i| i.name == old_name }
return unless old_index_def
@@ -835,11 +838,14 @@ module ActiveRecord
columns
end
- # Adds timestamps (+created_at+ and +updated_at+) columns to the named table.
+ include TimestampDefaultDeprecation
+ # Adds timestamps (+created_at+ and +updated_at+) columns to +table_name+.
+ # Additional options (like <tt>null: false</tt>) are forwarded to #add_column.
#
- # add_timestamps(:suppliers)
+ # add_timestamps(:suppliers, null: false)
#
def add_timestamps(table_name, options = {})
+ emit_warning_if_null_unspecified(options)
add_column table_name, :created_at, :datetime, options
add_column table_name, :updated_at, :datetime, options
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 57aa2f9c58..e0a4af5359 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -24,6 +24,7 @@ module ActiveRecord
autoload :TableDefinition
autoload :Table
autoload :AlterTable
+ autoload :TimestampDefaultDeprecation
end
autoload_at 'active_record/connection_adapters/abstract/connection_pool' do
@@ -264,7 +265,7 @@ module ActiveRecord
# Returns a bind substitution value given a bind +column+
# NOTE: The column param is currently being used by the sqlserver-adapter
- def substitute_at(column)
+ def substitute_at(column, _unused = 0)
Arel::Nodes::BindParam.new
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 167453657d..c824a7b11b 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -285,7 +285,9 @@ module ActiveRecord
end
end
+ #--
# DATABASE STATEMENTS ======================================
+ #++
def clear_cache!
super
diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb
index 609ec7dabd..e54e3199ff 100644
--- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb
+++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb
@@ -234,7 +234,7 @@ module ActiveRecord
end
end
- # Takes the environment such as `:production` or `:development`.
+ # Takes the environment such as +:production+ or +:development+.
# This requires that the @configurations was initialized with a key that
# matches.
#
diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index 5b83131f0e..d19bd80576 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -66,7 +66,9 @@ module ActiveRecord
exception.error_number if exception.respond_to?(:error_number)
end
+ #--
# QUOTING ==================================================
+ #++
def quote_string(string)
@connection.escape(string)
@@ -80,7 +82,9 @@ module ActiveRecord
end
end
+ #--
# CONNECTION MANAGEMENT ====================================
+ #++
def active?
return false unless @connection
@@ -104,7 +108,9 @@ module ActiveRecord
end
end
+ #--
# DATABASE STATEMENTS ======================================
+ #++
def explain(arel, binds = [])
sql = "EXPLAIN #{to_sql(arel, binds.dup)}"
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 3357ed52e5..53ad71b445 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -58,7 +58,7 @@ module ActiveRecord
# * <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>:variables</tt> - (Optional) A hash session variables to send as `SET @@SESSION.key = value` 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>: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.
# * <tt>:sslcert</tt> - Necessary to use MySQL with an SSL connection.
@@ -137,7 +137,9 @@ module ActiveRecord
@connection.quote(string)
end
+ #--
# CONNECTION MANAGEMENT ====================================
+ #++
def active?
if @connection.respond_to?(:stat)
@@ -178,7 +180,9 @@ module ActiveRecord
end
end
+ #--
# DATABASE STATEMENTS ======================================
+ #++
def select_rows(sql, name = nil, binds = [])
@connection.query_with_result = true
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
index f95f45c689..991c41327f 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
@@ -14,22 +14,6 @@ module ActiveRecord
@connection.unescape_bytea(value) if value
end
- # Quotes PostgreSQL-specific data types for SQL input.
- def quote(value, column = nil) #:nodoc:
- return super unless column
-
- case value
- when Float
- if value.infinite? || value.nan?
- "'#{value}'"
- else
- super
- end
- else
- super
- end
- end
-
# Quotes strings for use in SQL input.
def quote_string(s) #:nodoc:
@connection.escape(s)
@@ -94,6 +78,12 @@ module ActiveRecord
elsif value.hex?
"X'#{value}'"
end
+ when Float
+ if value.infinite? || value.nan?
+ "'#{value}'"
+ else
+ super
+ end
else
super
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
index 51853c6812..193c950261 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -411,7 +411,10 @@ module ActiveRecord
pk, seq = pk_and_sequence_for(new_name)
if seq && seq.identifier == "#{table_name}_#{pk}_seq"
new_seq = "#{new_name}_#{pk}_seq"
+ idx = "#{table_name}_pkey"
+ new_idx = "#{new_name}_pkey"
execute "ALTER TABLE #{quote_table_name(seq)} RENAME TO #{quote_table_name(new_seq)}"
+ execute "ALTER INDEX #{quote_table_name(idx)} RENAME TO #{quote_table_name(new_idx)}"
end
rename_table_indexes(table_name, new_name)
@@ -430,7 +433,12 @@ module ActiveRecord
quoted_table_name = quote_table_name(table_name)
sql_type = type_to_sql(type, options[:limit], options[:precision], options[:scale])
sql_type << "[]" if options[:array]
- execute "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{sql_type}"
+ sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{sql_type}"
+ sql << " USING #{options[:using]}" if options[:using]
+ if options[:cast_as]
+ sql << " USING CAST(#{quote_column_name(column_name)} AS #{type_to_sql(options[:cast_as], options[:limit], options[:precision], options[:scale])})"
+ end
+ execute sql
change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
@@ -478,6 +486,9 @@ module ActiveRecord
end
def rename_index(table_name, old_name, new_name)
+ if new_name.length > allowed_index_name_length
+ raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{allowed_index_name_length} characters"
+ end
execute "ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}"
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 6310d70192..3698957d8d 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -125,7 +125,7 @@ module ActiveRecord
PostgreSQL::SchemaCreation.new self
end
- # Adds `:array` option to the default set provided by the
+ # Adds +:array+ option to the default set provided by the
# AbstractAdapter
def prepare_column_options(column, types) # :nodoc:
spec = super
@@ -134,7 +134,7 @@ module ActiveRecord
spec
end
- # Adds `:array` as a valid migration key
+ # Adds +:array+ as a valid migration key
def migration_keys
super + [:array]
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index b18cb353f1..0b8b6a2bf8 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -266,7 +266,9 @@ module ActiveRecord
end
end
+ #--
# DATABASE STATEMENTS ======================================
+ #++
def explain(arel, binds = [])
sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index db6421dacb..7c53ee0a9a 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -806,7 +806,9 @@ module ActiveRecord
def find
if model_class
- model_class.find(fixture[model_class.primary_key])
+ model_class.unscoped do
+ model_class.find(fixture[model_class.primary_key])
+ end
else
raise FixtureClassNotFound, "No class attached to find."
end
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 2024b225e4..92f2951f2d 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -184,8 +184,8 @@ module ActiveRecord
# you wish to downgrade. Alternatively, you can also use the STEP option if you
# wish to rollback last few migrations. <tt>rake db:migrate STEP=2</tt> will rollback
# the latest two migrations.
- #
- # If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
+ #
+ # If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
# that step will fail and you'll have some manual work to do.
#
# == Database support
@@ -395,7 +395,14 @@ module ActiveRecord
def load_schema_if_pending!
if ActiveRecord::Migrator.needs_migration? || !ActiveRecord::Migrator.any_migrations?
- ActiveRecord::Tasks::DatabaseTasks.load_schema_current_if_exists
+ # Roundrip to Rake to allow plugins to hook into database initialization.
+ FileUtils.cd Rails.root do
+ current_config = Base.connection_config
+ Base.clear_all_connections!
+ system("bin/rake db:test:prepare")
+ # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
+ Base.establish_connection(current_config)
+ end
check_pending!
end
end
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index a4ceacbf44..f1bdbc845c 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -36,8 +36,6 @@ module ActiveRecord
config.eager_load_namespaces << ActiveRecord
rake_tasks do
- require "active_record/base"
-
namespace :db do
task :load_config do
ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index 3ec25f9f17..21b1c3f721 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -305,7 +305,7 @@ db_namespace = namespace :db do
end
# desc "Recreate the test database from the current schema"
- task :load => %w(db:test:deprecated db:test:purge) do
+ task :load => %w(db:test:purge) do
case ActiveRecord::Base.schema_format
when :ruby
db_namespace["test:load_schema"].invoke
@@ -315,7 +315,7 @@ db_namespace = namespace :db do
end
# desc "Recreate the test database from an existent schema.rb file"
- task :load_schema => %w(db:test:deprecated db:test:purge) do
+ task :load_schema => %w(db:test:purge) do
begin
should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
ActiveRecord::Schema.verbose = false
@@ -328,7 +328,7 @@ db_namespace = namespace :db do
end
# desc "Recreate the test database from an existent structure.sql file"
- task :load_structure => %w(db:test:deprecated db:test:purge) do
+ task :load_structure => %w(db:test:purge) do
ActiveRecord::Tasks::DatabaseTasks.load_schema_for ActiveRecord::Base.configurations['test'], :sql, ENV['SCHEMA']
end
@@ -349,12 +349,12 @@ db_namespace = namespace :db do
task :clone_structure => %w(db:test:deprecated db:structure:dump db:test:load_structure)
# desc "Empty the test database"
- task :purge => %w(db:test:deprecated environment load_config) do
+ task :purge => %w(environment load_config) do
ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations['test']
end
# desc 'Check for pending migrations and load the test schema'
- task :prepare => %w(db:test:deprecated environment load_config) do
+ task :prepare => %w(environment load_config) do
unless ActiveRecord::Base.configurations.blank?
db_namespace['test:load'].invoke
end
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index f4a351b092..4219632596 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -63,7 +63,7 @@ module ActiveRecord
# Returns a Hash of name of the reflection as the key and a AssociationReflection as the value.
#
- # Account.reflections # => {balance: AggregateReflection}
+ # Account.reflections # => {"balance" => AggregateReflection}
#
# @api public
def reflections
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 460daf99bc..561ed222d1 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -304,11 +304,11 @@ module ActiveRecord
klass.current_scope = previous
end
- # Updates all records with details given if they match a set of conditions supplied, limits and order can
- # also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the
- # database. It does not instantiate the involved models and it does not trigger Active Record callbacks
- # or validations. Values passed to `update_all` will not go through ActiveRecord's type-casting behavior.
- # It should receive only values that can be passed as-is to the SQL database.
+ # Updates all records in the current relation with details given. This method constructs a single SQL UPDATE
+ # statement and sends it straight to the database. It does not instantiate the involved models and it does not
+ # trigger Active Record callbacks or validations. Values passed to `update_all` will not go through
+ # ActiveRecord's type-casting behavior. It should receive only values that can be passed as-is to the SQL
+ # database.
#
# ==== Parameters
#
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index cb4e33f1b1..6e384facce 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -427,14 +427,12 @@ module ActiveRecord
# => SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id
def joins(*args)
check_if_method_has_arguments!(:joins, args)
-
- args.compact!
- args.flatten!
-
spawn.joins!(*args)
end
def joins!(*args) # :nodoc:
+ args.compact!
+ args.flatten!
self.joins_values += args
self
end
@@ -1059,8 +1057,13 @@ module ActiveRecord
def build_select(arel, selects)
if !selects.empty?
expanded_select = selects.map do |field|
- columns_hash.key?(field.to_s) ? arel_table[field] : field
+ if (Symbol === field || String === field) && columns_hash.key?(field.to_s)
+ arel_table[field]
+ else
+ field
+ end
end
+
arel.project(*expanded_select)
else
arel.project(@klass.arel_table[Arel.star])
diff --git a/activerecord/lib/active_record/type/integer.rb b/activerecord/lib/active_record/type/integer.rb
index 36bbd9cd5e..750f353472 100644
--- a/activerecord/lib/active_record/type/integer.rb
+++ b/activerecord/lib/active_record/type/integer.rb
@@ -38,7 +38,7 @@ module ActiveRecord
def ensure_in_range(value)
unless range.cover?(value)
- raise RangeError, "#{value} is too large for #{self.class} with limit #{limit || 4}"
+ raise RangeError, "#{value} is out of range for #{self.class} with limit #{limit || 4}"
end
end
diff --git a/activerecord/lib/active_record/type/type_map.rb b/activerecord/lib/active_record/type/type_map.rb
index 7c194c0cdf..09f5ba6b74 100644
--- a/activerecord/lib/active_record/type/type_map.rb
+++ b/activerecord/lib/active_record/type/type_map.rb
@@ -1,10 +1,12 @@
+require 'thread_safe'
+
module ActiveRecord
module Type
class TypeMap # :nodoc:
def initialize
@mapping = {}
- @cache = Hash.new do |h, key|
- h[key] = {}
+ @cache = ThreadSafe::Cache.new do |h, key|
+ h.fetch_or_store(key, ThreadSafe::Cache.new)
end
end
@@ -13,7 +15,9 @@ module ActiveRecord
end
def fetch(lookup_key, *args, &block)
- @cache[lookup_key][args] ||= perform_fetch(lookup_key, *args, &block)
+ @cache[lookup_key].fetch_or_store(args) do
+ perform_fetch(lookup_key, *args, &block)
+ end
end
def register_type(key, value = nil, &block)