aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md121
-rw-r--r--activerecord/Rakefile2
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb2
-rw-r--r--activerecord/lib/active_record/core.rb2
-rw-r--r--activerecord/lib/active_record/fixtures.rb4
-rw-r--r--activerecord/lib/active_record/log_subscriber.rb2
-rw-r--r--activerecord/lib/active_record/railties/databases.rake2
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb21
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb2
-rw-r--r--activerecord/test/cases/associations/eager_test.rb3
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb22
-rw-r--r--activerecord/test/cases/associations/inverse_associations_test.rb14
-rw-r--r--activerecord/test/cases/attribute_methods/serialization_test.rb29
-rw-r--r--activerecord/test/cases/connection_pool_test.rb2
-rw-r--r--activerecord/test/cases/defaults_test.rb25
-rw-r--r--activerecord/test/cases/disconnected_test.rb26
-rw-r--r--activerecord/test/cases/fixtures_test.rb16
-rw-r--r--activerecord/test/cases/invalid_connection_test.rb20
-rw-r--r--activerecord/test/cases/log_subscriber_test.rb7
-rw-r--r--activerecord/test/cases/relation_test.rb9
25 files changed, 282 insertions, 71 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index ab1eb49286..4055dcd484 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,33 +1,98 @@
+* Flatten merged join_values before building the joins.
+
+ While joining_values special treatment is given to string values.
+ By flattening the array it ensures that string values are detected
+ as strings and not arrays.
+
+ Fixes #10669.
+
+ *Neeraj Singh and iwiznia*
+
+* Do not load all child records for inverse case.
+
+ currently `post.comments.find(Comment.first.id)` would load all
+ comments for the given post to set the inverse association.
+
+ This has a huge performance penalty. Because if post has 100k
+ records and all these 100k records would be loaded in memory
+ even though the comment id was supplied.
+
+ Fix is to use in-memory records only if loaded? is true. Otherwise
+ load the records using full sql.
+
+ Fixes #10509.
+
+ *Neeraj Singh*
+
+* `inspect` on Active Record model classes does not initiate a
+ new connection. This means that calling `inspect`, when the
+ database is missing, will no longer raise an exception.
+ Fixes #10936.
+
+ Example:
+
+ Author.inspect # => "Author(no database connection)"
+
+ *Yves Senn*
+
+* Handle single quotes in PostgreSQL default column values.
+ Fixes #10881.
+
+ *Dylan Markow*
+
+* Log the sql that is actually sent to the database.
+
+ If I have a query that produces sql
+ `WHERE "users"."name" = 'a b'` then in the log all the
+ whitespace is being squeezed. So the sql that is printed in the
+ log is `WHERE "users"."name" = 'a b'`.
+
+ Do not squeeze whitespace out of sql queries. Fixes #10982.
+
+ *Neeraj Singh*
+
+* Fixture setup does no longer depend on `ActiveRecord::Base.configurations`.
+ This is relevant when `ENV["DATABASE_URL"]` is used in place of a `database.yml`.
+
+ *Yves Senn*
+
+* Fix mysql2 adapter raises the correct exception when executing a query on a
+ closed connection.
+
+ *Yves Senn*
+
* Ambiguous reflections are on :through relationships are no longer supported.
For example, you need to change this:
- class Author < ActiveRecord::Base
- has_many :posts
- has_many :taggings, :through => :posts
- end
-
- class Post < ActiveRecord::Base
- has_one :tagging
- has_many :taggings
- end
-
- class Tagging < ActiveRecord::Base
- end
+ class Author < ActiveRecord::Base
+ has_many :posts
+ has_many :taggings, :through => :posts
+ end
+
+ class Post < ActiveRecord::Base
+ has_one :tagging
+ has_many :taggings
+ end
+
+ class Tagging < ActiveRecord::Base
+ end
To this:
- class Author < ActiveRecord::Base
- has_many :posts
- has_many :taggings, :through => :posts, :source => :tagging
- end
-
- class Post < ActiveRecord::Base
- has_one :tagging
- has_many :taggings
- end
-
- class Tagging < ActiveRecord::Base
- end
+ class Author < ActiveRecord::Base
+ has_many :posts
+ has_many :taggings, :through => :posts, :source => :tagging
+ end
+
+ class Post < ActiveRecord::Base
+ has_one :tagging
+ has_many :taggings
+ end
+
+ class Tagging < ActiveRecord::Base
+ end
+
+ *Aaron Peterson*
* Remove column restrictions for `count`, let the database raise if the SQL is
invalid. The previous behavior was untested and surprising for the user.
@@ -60,9 +125,9 @@
You can turn off the automatic detection of inverse associations by setting
the `:inverse_of` option to `false` like so:
- class Taggable < ActiveRecord::Base
- belongs_to :tag, inverse_of: false
- end
+ class Taggable < ActiveRecord::Base
+ belongs_to :tag, inverse_of: false
+ end
*John Wang*
@@ -100,7 +165,7 @@
* Deprecate `ConnectionAdapters::SchemaStatements#distinct`,
as it is no longer used by internals.
- *Ben Woosley#
+ *Ben Woosley*
* Fix pending migrations error when loading schema and `ActiveRecord::Base.table_name_prefix`
is not blank.
diff --git a/activerecord/Rakefile b/activerecord/Rakefile
index 136bb1dfbc..df0193e1b5 100644
--- a/activerecord/Rakefile
+++ b/activerecord/Rakefile
@@ -222,7 +222,7 @@ end
# Publishing ------------------------------------------------------
-desc "Release to gemcutter"
+desc "Release to rubygems"
task :release => :package do
require 'rake/gemcutter'
Rake::Gemcutter::Tasks.new(spec).define
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index efd7ecb97c..9833822f8f 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -81,7 +81,7 @@ module ActiveRecord
else
if options[:finder_sql]
find_by_scan(*args)
- elsif options[:inverse_of]
+ elsif options[:inverse_of] && loaded?
args = args.flatten
raise RecordNotFound, "Couldn't find #{scope.klass.name} without an ID" if args.blank?
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index e82c195335..7cdb5ba5b3 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -830,7 +830,7 @@ module ActiveRecord
# person.pets.include?(Pet.find(20)) # => true
# person.pets.include?(Pet.find(21)) # => false
def include?(record)
- @association.include?(record)
+ !!@association.include?(record)
end
def proxy_association
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index 9caf73e627..1287de0d0d 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -56,7 +56,11 @@ module ActiveRecord
end
def type_cast(value)
- value.unserialized_value @column.type_cast value.value
+ if value.state == :serialized
+ value.unserialized_value @column.type_cast value.value
+ else
+ value.unserialized_value
+ end
end
def type
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 3ac55a0f11..9a1923dec5 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -214,8 +214,8 @@ module ActiveRecord
# its block form to do so yourself:
#
# create_join_table :products, :categories do |t|
- # t.index :products
- # t.index :categories
+ # t.index :product_id
+ # t.index :category_id
# end
#
# ====== Add a backend specific option to the generated SQL (MySQL)
diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index 530a27d099..edeb338310 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -213,9 +213,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/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index d5a603cadc..98126249df 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -84,7 +84,7 @@ module ActiveRecord
$1
# Character types
when /\A\(?'(.*)'::.*\b(?:character varying|bpchar|text)\z/m
- $1
+ $1.gsub(/''/, "'")
# Binary data types
when /\A'(.*)'::bytea\z/m
$1
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index ba053700f2..f0141aaaab 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -123,6 +123,8 @@ module ActiveRecord
super
elsif abstract_class?
"#{super}(abstract)"
+ elsif !connected?
+ "#{super}(no database connection)"
elsif table_exists?
attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
"#{super}(#{attr_list})"
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 33e19313a0..70eda332b3 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -841,8 +841,6 @@ module ActiveRecord
end
def setup_fixtures
- return if ActiveRecord::Base.configurations.blank?
-
if pre_loaded_fixtures && !use_transactional_fixtures
raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures'
end
@@ -875,8 +873,6 @@ module ActiveRecord
end
def teardown_fixtures
- return if ActiveRecord::Base.configurations.blank?
-
# Rollback changes if a transaction is active.
if run_in_transaction?
@fixture_connections.each do |connection|
diff --git a/activerecord/lib/active_record/log_subscriber.rb b/activerecord/lib/active_record/log_subscriber.rb
index 61e5c120df..0358a36b14 100644
--- a/activerecord/lib/active_record/log_subscriber.rb
+++ b/activerecord/lib/active_record/log_subscriber.rb
@@ -41,7 +41,7 @@ module ActiveRecord
return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
name = "#{payload[:name]} (#{event.duration.round(1)}ms)"
- sql = payload[:sql].squeeze(' ')
+ sql = payload[:sql]
binds = nil
unless (payload[:binds] || []).empty?
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index f69e9b2217..0b74553bf8 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -324,7 +324,7 @@ db_namespace = namespace :db do
ActiveRecord::Schema.verbose = false
db_namespace["schema:load"].invoke
ensure
- ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[Rails.env])
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[ActiveRecord::Tasks::DatabaseTasks.env])
end
end
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 1550d702a6..3ea3c33fcc 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -124,11 +124,7 @@ module ActiveRecord
#
def first(limit = nil)
if limit
- if order_values.empty? && primary_key
- order(arel_table[primary_key].asc).limit(limit).to_a
- else
- limit(limit).to_a
- end
+ find_first_with_limit(order_values, limit)
else
find_first
end
@@ -358,12 +354,15 @@ module ActiveRecord
if loaded?
@records.first
else
- @first ||=
- if with_default_scope.order_values.empty? && primary_key
- order(arel_table[primary_key].asc).limit(1).to_a.first
- else
- limit(1).to_a.first
- end
+ @first ||= find_first_with_limit(with_default_scope.order_values, 1).first
+ end
+ end
+
+ def find_first_with_limit(order_values, limit)
+ if order_values.empty? && primary_key
+ order(arel_table[primary_key].asc).limit(limit).to_a
+ else
+ limit(limit).to_a
end
end
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index ca1de2d4dc..0200fcf69b 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -802,7 +802,7 @@ module ActiveRecord
def build_arel
arel = Arel::SelectManager.new(table.engine, table)
- build_joins(arel, joins_values) unless joins_values.empty?
+ build_joins(arel, joins_values.flatten) unless joins_values.empty?
collapse_wheres(arel, (where_values - ['']).uniq)
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 4aa6567d85..1cfaf552af 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -250,7 +250,8 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert_nil Post.all.merge!(:includes => :author).find(posts(:authorless).id).author
end
- def test_nested_loading_with_no_associations
+ # Regression test for 21c75e5
+ def test_nested_loading_does_not_raise_exception_when_association_does_not_exist
assert_nothing_raised do
Post.all.merge!(:includes => {:author => :author_addresss}).find(posts(:authorless).id)
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 9f64ecd845..168ce13097 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -418,7 +418,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
client_ary = firm.clients_using_finder_sql.find("2", "3")
assert_kind_of Array, client_ary
assert_equal 2, client_ary.size
- assert client_ary.include?(client)
+ assert_equal true, client_ary.include?(client)
end
def test_find_all
@@ -1220,14 +1220,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_included_in_collection
- assert companies(:first_firm).clients.include?(Client.find(2))
+ assert_equal true, companies(:first_firm).clients.include?(Client.find(2))
end
def test_included_in_collection_for_new_records
client = Client.create(:name => 'Persisted')
assert_nil client.client_of
- assert !Firm.new.clients_of_firm.include?(client),
- 'includes a client that does not belong to any firm'
+ assert_equal false, Firm.new.clients_of_firm.include?(client),
+ 'includes a client that does not belong to any firm'
end
def test_adding_array_and_collection
@@ -1254,7 +1254,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
firm.save
firm.reload
assert_equal 2, firm.clients.length
- assert !firm.clients.include?(:first_client)
+ assert_equal false, firm.clients.include?(:first_client)
end
def test_replace_failure
@@ -1332,7 +1332,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
firm.save!
assert_equal 2, firm.clients(true).size
- assert firm.clients.include?(companies(:second_client))
+ assert_equal true, firm.clients.include?(companies(:second_client))
end
def test_get_ids_for_through
@@ -1366,7 +1366,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_no_queries do
assert firm.clients.loaded?
- assert firm.clients.include?(client)
+ assert_equal true, firm.clients.include?(client)
end
end
@@ -1377,7 +1377,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
firm.reload
assert ! firm.clients.loaded?
assert_queries(1) do
- assert firm.clients.include?(client)
+ assert_equal true, firm.clients.include?(client)
end
assert ! firm.clients.loaded?
end
@@ -1388,7 +1388,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
firm.reload
assert ! firm.clients_using_sql.loaded?
- assert firm.clients_using_sql.include?(client)
+ assert_equal true, firm.clients_using_sql.include?(client)
assert firm.clients_using_sql.loaded?
end
@@ -1398,7 +1398,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
client = Client.create!(:name => 'Not Associated')
assert ! firm.clients.loaded?
- assert ! firm.clients.include?(client)
+ assert_equal false, firm.clients.include?(client)
end
def test_calling_first_or_last_on_association_should_not_load_association
@@ -1613,7 +1613,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_include_method_in_has_many_association_should_return_true_for_instance_added_with_build
post = Post.new
comment = post.comments.build
- assert post.comments.include?(comment)
+ assert_equal true, post.comments.include?(comment)
end
def test_load_target_respects_protected_attributes
diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb
index b1f0be3204..71cf1237e8 100644
--- a/activerecord/test/cases/associations/inverse_associations_test.rb
+++ b/activerecord/test/cases/associations/inverse_associations_test.rb
@@ -401,10 +401,22 @@ class InverseHasManyTests < ActiveRecord::TestCase
assert_equal man.name, man.interests.find(interest.id).man.name, "The name of the man should match after the child name is changed"
end
+ def test_find_on_child_instance_with_id_should_not_load_all_child_records
+ man = Man.create!
+ interest = Interest.create!(man: man)
+
+ man.interests.find(interest.id)
+ refute man.interests.loaded?
+ end
+
def test_raise_record_not_found_error_when_invalid_ids_are_passed
+ # delete all interest records to ensure that hard coded invalid_id(s)
+ # are indeed invalid.
+ Interest.delete_all
+
man = Man.create!
- invalid_id = 2394823094892348920348523452345
+ invalid_id = 245324523
assert_raise(ActiveRecord::RecordNotFound) { man.interests.find(invalid_id) }
invalid_ids = [8432342, 2390102913, 2453245234523452]
diff --git a/activerecord/test/cases/attribute_methods/serialization_test.rb b/activerecord/test/cases/attribute_methods/serialization_test.rb
new file mode 100644
index 0000000000..75de773961
--- /dev/null
+++ b/activerecord/test/cases/attribute_methods/serialization_test.rb
@@ -0,0 +1,29 @@
+require "cases/helper"
+
+module ActiveRecord
+ module AttributeMethods
+ class SerializationTest < ActiveSupport::TestCase
+ class FakeColumn < Struct.new(:name)
+ def type; :integer; end
+ def type_cast(s); "#{s}!"; end
+ end
+
+ class NullCoder
+ def load(v); v; end
+ end
+
+ def test_type_cast_serialized_value
+ value = Serialization::Attribute.new(NullCoder.new, "Hello world", :serialized)
+ type = Serialization::Type.new(FakeColumn.new)
+ assert_equal "Hello world!", type.type_cast(value)
+ end
+
+ def test_type_cast_unserialized_value
+ value = Serialization::Attribute.new(nil, "Hello world", :unserialized)
+ type = Serialization::Type.new(FakeColumn.new)
+ type.type_cast(value)
+ assert_equal "Hello world", type.type_cast(value)
+ end
+ end
+ end
+end
diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb
index e6af29282c..d5365b695e 100644
--- a/activerecord/test/cases/connection_pool_test.rb
+++ b/activerecord/test/cases/connection_pool_test.rb
@@ -329,7 +329,7 @@ module ActiveRecord
end
# make sure exceptions are thrown when establish_connection
- # is called with a anonymous class
+ # is called with an anonymous class
def test_anonymous_class_exception
anonymous = Class.new(ActiveRecord::Base)
handler = ActiveRecord::Base.connection_handler
diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb
index e0cf4adf13..7e3d91e08c 100644
--- a/activerecord/test/cases/defaults_test.rb
+++ b/activerecord/test/cases/defaults_test.rb
@@ -39,6 +39,31 @@ class DefaultTest < ActiveRecord::TestCase
end
end
+class DefaultStringsTest < ActiveRecord::TestCase
+ class DefaultString < ActiveRecord::Base; end
+
+ setup do
+ @connection = ActiveRecord::Base.connection
+ @connection.create_table :default_strings do |t|
+ t.string :string_col, default: "Smith"
+ t.string :string_col_with_quotes, default: "O'Connor"
+ end
+ DefaultString.reset_column_information
+ end
+
+ def test_default_strings
+ assert_equal "Smith", DefaultString.new.string_col
+ end
+
+ def test_default_strings_containing_single_quotes
+ assert_equal "O'Connor", DefaultString.new.string_col_with_quotes
+ end
+
+ teardown do
+ @connection.drop_table :default_strings
+ end
+end
+
if current_adapter?(:MysqlAdapter, :Mysql2Adapter)
class DefaultsTestWithoutTransactionalFixtures < ActiveRecord::TestCase
# ActiveRecord::Base#create! (and #save and other related methods) will
diff --git a/activerecord/test/cases/disconnected_test.rb b/activerecord/test/cases/disconnected_test.rb
new file mode 100644
index 0000000000..cc2c1f6489
--- /dev/null
+++ b/activerecord/test/cases/disconnected_test.rb
@@ -0,0 +1,26 @@
+require "cases/helper"
+
+class TestRecord < ActiveRecord::Base
+end
+
+class TestDisconnectedAdapter < ActiveRecord::TestCase
+ self.use_transactional_fixtures = false
+
+ def setup
+ @connection = ActiveRecord::Base.connection
+ end
+
+ def teardown
+ spec = ActiveRecord::Base.connection_config
+ ActiveRecord::Base.establish_connection(spec)
+ @connection = nil
+ end
+
+ test "can't execute statements while disconnected" do
+ @connection.execute "SELECT count(*) from products"
+ @connection.disconnect!
+ assert_raises(ActiveRecord::StatementInvalid) do
+ @connection.execute "SELECT count(*) from products"
+ end
+ end
+end
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index f6cfee0cb8..df6edc4057 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -245,6 +245,22 @@ class FixturesTest < ActiveRecord::TestCase
def test_serialized_fixtures
assert_equal ["Green", "Red", "Orange"], traffic_lights(:uk).state
end
+
+ def test_fixtures_are_set_up_with_database_env_variable
+ ENV.stubs(:[]).with("DATABASE_URL").returns("sqlite3:///:memory:")
+ ActiveRecord::Base.stubs(:configurations).returns({})
+ test_case = Class.new(ActiveRecord::TestCase) do
+ fixtures :accounts
+
+ def test_fixtures
+ assert accounts(:signals37)
+ end
+ end
+
+ result = test_case.new(:test_fixtures).run
+
+ assert result.passed?, "Expected #{result.name} to pass:\n#{result}"
+ end
end
if Account.connection.respond_to?(:reset_pk_sequence!)
diff --git a/activerecord/test/cases/invalid_connection_test.rb b/activerecord/test/cases/invalid_connection_test.rb
new file mode 100644
index 0000000000..f6fe7f0d7d
--- /dev/null
+++ b/activerecord/test/cases/invalid_connection_test.rb
@@ -0,0 +1,20 @@
+require "cases/helper"
+require "models/bird"
+
+class TestAdapterWithInvalidConnection < ActiveRecord::TestCase
+ self.use_transactional_fixtures = false
+
+ def setup
+ @spec = ActiveRecord::Base.connection_config
+ non_existing_spec = {adapter: @spec[:adapter], database: "i_do_not_exist"}
+ ActiveRecord::Base.establish_connection(non_existing_spec)
+ end
+
+ def teardown
+ ActiveRecord::Base.establish_connection(@spec)
+ end
+
+ test "inspect on Model class does not raise" do
+ assert_equal "Bird(no database connection)", Bird.inspect
+ end
+end
diff --git a/activerecord/test/cases/log_subscriber_test.rb b/activerecord/test/cases/log_subscriber_test.rb
index 57eac0c175..3bdc5a1302 100644
--- a/activerecord/test/cases/log_subscriber_test.rb
+++ b/activerecord/test/cases/log_subscriber_test.rb
@@ -56,6 +56,13 @@ class LogSubscriberTest < ActiveRecord::TestCase
assert_equal 2, logger.debugs.length
end
+ def test_sql_statements_are_not_squeezed
+ event = Struct.new(:duration, :payload)
+ logger = TestDebugLogSubscriber.new
+ logger.sql(event.new(0, sql: 'ruby rails'))
+ assert_match(/ruby rails/, logger.debugs.first)
+ end
+
def test_ignore_binds_payload_with_nil_column
event = Struct.new(:duration, :payload)
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb
index 55fd068d37..693b36f35c 100644
--- a/activerecord/test/cases/relation_test.rb
+++ b/activerecord/test/cases/relation_test.rb
@@ -176,7 +176,7 @@ module ActiveRecord
assert_equal ['foo = bar'], relation.where_values
end
- def test_relation_merging_with_merged_joins
+ def test_relation_merging_with_merged_joins_as_symbols
special_comments_with_ratings = SpecialComment.joins(:ratings)
posts_with_special_comments_with_ratings = Post.group("posts.id").joins(:special_comments).merge(special_comments_with_ratings)
assert_equal 3, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count.length
@@ -190,6 +190,13 @@ module ActiveRecord
assert_equal false, post.respond_to?(:title), "post should not respond_to?(:body) since invoking it raises exception"
end
+ def test_relation_merging_with_merged_joins_as_strings
+ join_string = "LEFT OUTER JOIN #{Rating.quoted_table_name} ON #{SpecialComment.quoted_table_name}.id = #{Rating.quoted_table_name}.comment_id"
+ special_comments_with_ratings = SpecialComment.joins join_string
+ posts_with_special_comments_with_ratings = Post.group("posts.id").joins(:special_comments).merge(special_comments_with_ratings)
+ assert_equal 3, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count.length
+ end
+
end
class RelationMutationTest < ActiveSupport::TestCase