aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/connection_specification.rb6
-rw-r--r--activerecord/lib/active_record/connection_handling.rb35
-rw-r--r--activerecord/lib/active_record/enum.rb9
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb2
-rw-r--r--activerecord/test/cases/connection_adapters/connection_handler_test.rb71
-rw-r--r--activerecord/test/cases/enum_test.rb35
6 files changed, 89 insertions, 69 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb
index e0715f7ce9..a8ab52be74 100644
--- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb
+++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb
@@ -33,7 +33,7 @@ module ActiveRecord
def initialize(url)
raise "Database URL cannot be empty" if url.blank?
@uri = URI.parse(url)
- @adapter = @uri.scheme
+ @adapter = @uri.scheme.gsub('-', '_')
@adapter = "postgresql" if @adapter == "postgres"
if @uri.opaque
@@ -220,10 +220,10 @@ module ActiveRecord
# an environment key or a URL spec, so we have deprecated
# this ambiguous behaviour and in the future this function
# can be removed in favor of resolve_url_connection.
- if configurations.key?(spec)
+ if configurations.key?(spec) || spec !~ /:/
ActiveSupport::Deprecation.warn "Passing a string to ActiveRecord::Base.establish_connection " \
"for a configuration lookup is deprecated, please pass a symbol (#{spec.to_sym.inspect}) instead"
- resolve_connection(configurations[spec])
+ resolve_symbol_connection(spec)
else
resolve_url_connection(spec)
end
diff --git a/activerecord/lib/active_record/connection_handling.rb b/activerecord/lib/active_record/connection_handling.rb
index bbb866cedf..31e7390bf7 100644
--- a/activerecord/lib/active_record/connection_handling.rb
+++ b/activerecord/lib/active_record/connection_handling.rb
@@ -58,9 +58,9 @@ module ActiveRecord
end
class MergeAndResolveDefaultUrlConfig # :nodoc:
- def initialize(raw_configurations, url = ENV['DATABASE_URL'])
+ def initialize(raw_configurations)
@raw_config = raw_configurations.dup
- @url = url
+ @env = DEFAULT_ENV.call.to_s
end
# Returns fully resolved connection hashes.
@@ -71,33 +71,10 @@ module ActiveRecord
private
def config
- if @url
- raw_merged_into_default
- else
- @raw_config
- end
- end
-
- def raw_merged_into_default
- default = default_url_hash
-
- @raw_config.each do |env, values|
- default[env] = values || {}
- default[env].merge!("url" => @url) { |h, v1, v2| v1 || v2 } if default[env].is_a?(Hash)
- end
- default
- end
-
- # When the raw configuration is not present and ENV['DATABASE_URL']
- # is available we return a hash with the connection information in
- # the connection URL. This hash responds to any string key with
- # resolved connection information.
- def default_url_hash
- Hash.new do |hash, key|
- hash[key] = if key.is_a? String
- ActiveRecord::ConnectionAdapters::ConnectionSpecification::ConnectionUrlResolver.new(@url).to_hash
- else
- nil
+ @raw_config.dup.tap do |cfg|
+ if url = ENV['DATABASE_URL']
+ cfg[@env] ||= {}
+ cfg[@env]["url"] ||= url
end
end
end
diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb
index 167f8b7a49..18f1ca26de 100644
--- a/activerecord/lib/active_record/enum.rb
+++ b/activerecord/lib/active_record/enum.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/deep_dup'
+
module ActiveRecord
# Declare an enum attribute where the values map to integers in the database,
# but can be queried by name. Example:
@@ -70,8 +72,9 @@ module ActiveRecord
base.defined_enums = {}
end
- def enum_mapping_for(attr_name) # :nodoc:
- defined_enums[attr_name.to_s]
+ def inherited(base)
+ base.defined_enums = defined_enums.deep_dup
+ super
end
def enum(definitions)
@@ -136,7 +139,7 @@ module ActiveRecord
mod = Module.new do
private
def save_changed_attribute(attr_name, value)
- if (mapping = self.class.enum_mapping_for(attr_name))
+ if (mapping = self.class.defined_enums[attr_name.to_s])
if attribute_changed?(attr_name)
old = changed_attributes[attr_name]
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 71c71cb4b1..ee080451a9 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -93,7 +93,7 @@ module ActiveRecord
end
def map_enum_attribute(klass, attribute, value)
- mapping = klass.enum_mapping_for(attribute.to_s)
+ mapping = klass.defined_enums[attribute.to_s]
value = mapping[value] if value && mapping
value
end
diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
index e097449029..f2d18e812d 100644
--- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb
+++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
@@ -25,35 +25,45 @@ module ActiveRecord
ConnectionSpecification::Resolver.new(klass.new(config).resolve).spec(spec)
end
- def test_resolver_with_database_uri_and_known_key
+ def test_resolver_with_database_uri_and_current_env_symbol_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
- config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
- actual = resolve(:production, config)
+ config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
+ actual = resolve(:default_env, config)
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end
- def test_resolver_with_database_uri_and_known_string_key
+ def test_resolver_with_database_uri_and_and_current_env_string_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
- config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
- actual = assert_deprecated { resolve("production", config) }
+ config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo" } }
+ actual = assert_deprecated { resolve("default_env", config) }
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end
- def test_resolver_with_database_uri_and_unknown_symbol_key
+ def test_resolver_with_database_uri_and_known_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
- config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
+ config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
actual = resolve(:production, config)
- expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
+ expected = { "adapter"=>"not_postgres", "database"=>"not_foo", "host"=>"localhost" }
assert_equal expected, actual
end
- def test_resolver_with_database_uri_and_unknown_string_key
+ def test_resolver_with_database_uri_and_unknown_symbol_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
assert_raises AdapterNotSpecified do
- spec("production", config)
+ resolve(:production, config)
+ end
+ end
+
+ def test_resolver_with_database_uri_and_unknown_string_key
+ ENV['DATABASE_URL'] = "postgres://localhost/foo"
+ config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
+ assert_deprecated do
+ assert_raises AdapterNotSpecified do
+ spec("production", config)
+ end
end
end
@@ -73,16 +83,24 @@ module ActiveRecord
def test_environment_does_not_exist_in_config_url_does_exist
ENV['DATABASE_URL'] = "postgres://localhost/foo"
- config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
+ config = { "not_default_env" => { "adapter" => "not_postgres", "database" => "not_foo" } }
actual = klass.new(config).resolve
expect_prod = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
- assert_equal expect_prod, actual["production"]
+ assert_equal expect_prod, actual["default_env"]
+ end
+
+ def test_url_with_hyphenated_scheme
+ ENV['DATABASE_URL'] = "ibm-db://localhost/foo"
+ config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
+ actual = resolve(:default_env, config)
+ expected = { "adapter"=>"ibm_db", "database"=>"foo", "host"=>"localhost" }
+ assert_equal expected, actual
end
def test_string_connection
- config = { "production" => "postgres://localhost/foo" }
+ config = { "default_env" => "postgres://localhost/foo" }
actual = klass.new(config).resolve
- expected = { "production" =>
+ expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost"
@@ -92,9 +110,9 @@ module ActiveRecord
end
def test_url_sub_key
- config = { "production" => { "url" => "postgres://localhost/foo" } }
+ config = { "default_env" => { "url" => "postgres://localhost/foo" } }
actual = klass.new(config).resolve
- expected = { "production" =>
+ expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost"
@@ -123,9 +141,10 @@ module ActiveRecord
expected = { "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost" }
- assert_equal expected, actual["production"]
- assert_equal expected, actual["development"]
- assert_equal expected, actual["test"]
+ assert_equal expected, actual["default_env"]
+ assert_equal nil, actual["production"]
+ assert_equal nil, actual["development"]
+ assert_equal nil, actual["test"]
assert_equal nil, actual[:production]
assert_equal nil, actual[:development]
assert_equal nil, actual[:test]
@@ -134,9 +153,9 @@ module ActiveRecord
def test_url_sub_key_with_database_url
ENV['DATABASE_URL'] = "NOT-POSTGRES://localhost/NOT_FOO"
- config = { "production" => { "url" => "postgres://localhost/foo" } }
+ config = { "default_env" => { "url" => "postgres://localhost/foo" } }
actual = klass.new(config).resolve
- expected = { "production" =>
+ expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost"
@@ -148,9 +167,9 @@ module ActiveRecord
def test_merge_no_conflicts_with_database_url
ENV['DATABASE_URL'] = "postgres://localhost/foo"
- config = {"production" => { "pool" => "5" } }
+ config = {"default_env" => { "pool" => "5" } }
actual = klass.new(config).resolve
- expected = { "production" =>
+ expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost",
@@ -163,9 +182,9 @@ module ActiveRecord
def test_merge_conflicts_with_database_url
ENV['DATABASE_URL'] = "postgres://localhost/foo"
- config = {"production" => { "adapter" => "NOT-POSTGRES", "database" => "NOT-FOO", "pool" => "5" } }
+ config = {"default_env" => { "adapter" => "NOT-POSTGRES", "database" => "NOT-FOO", "pool" => "5" } }
actual = klass.new(config).resolve
- expected = { "production" =>
+ expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost",
diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb
index 5157c272ca..3b2f0dfe07 100644
--- a/activerecord/test/cases/enum_test.rb
+++ b/activerecord/test/cases/enum_test.rb
@@ -252,17 +252,38 @@ class EnumTest < ActiveRecord::TestCase
end
test "enums are distinct per class" do
- Plane = Class.new(ActiveRecord::Base) do
- enum status: [:grounded, :operational]
+ klass1 = Class.new(ActiveRecord::Base) do
+ self.table_name = "books"
+ enum status: [:proposed, :written]
+ end
+
+ klass2 = Class.new(ActiveRecord::Base) do
+ self.table_name = "books"
+ enum status: [:drafted, :uploaded]
end
- assert_equal({ "proposed" => 0, "written" => 1, "published" => 2 }, Book.statuses)
- assert_equal({ "grounded" => 0, "operational" => 1 }, Plane.statuses)
+
+ book1 = klass1.proposed.create!
+ book1.status = :written
+ assert_equal ['proposed', 'written'], book1.status_change
+
+ book2 = klass2.drafted.create!
+ book2.status = :uploaded
+ assert_equal ['drafted', 'uploaded'], book2.status_change
end
test "enums are inheritable" do
- Encyclopedia = Class.new(Book) do
- enum status: [:published, :reprinted]
+ subklass1 = Class.new(Book)
+
+ subklass2 = Class.new(Book) do
+ enum status: [:drafted, :uploaded]
end
- assert_equal({ "published" => 0, "reprinted" => 1 }, Encyclopedia.statuses)
+
+ book1 = subklass1.proposed.create!
+ book1.status = :written
+ assert_equal ['proposed', 'written'], book1.status_change
+
+ book2 = subklass2.drafted.create!
+ book2.status = :uploaded
+ assert_equal ['drafted', 'uploaded'], book2.status_change
end
end