aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md13
-rw-r--r--activerecord/lib/active_record/associations.rb10
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb2
-rw-r--r--activerecord/lib/active_record/attribute.rb6
-rw-r--r--activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb6
-rw-r--r--activerecord/lib/active_record/attributes.rb30
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/quoting.rb25
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb49
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb5
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb18
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/enum.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/range.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/vector.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/xml.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb38
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb30
-rw-r--r--activerecord/lib/active_record/enum.rb23
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb2
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb2
-rw-r--r--activerecord/lib/active_record/relation/batches.rb48
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb4
-rw-r--r--activerecord/lib/active_record/result.rb2
-rw-r--r--activerecord/lib/active_record/sanitization.rb2
-rw-r--r--activerecord/lib/active_record/secure_token.rb3
-rw-r--r--activerecord/lib/active_record/type.rb46
-rw-r--r--activerecord/lib/active_record/type/adapter_specific_registry.rb142
-rw-r--r--activerecord/lib/active_record/type/binary.rb6
-rw-r--r--activerecord/lib/active_record/type/date_time.rb2
-rw-r--r--activerecord/lib/active_record/type/float.rb2
-rw-r--r--activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb2
-rw-r--r--activerecord/lib/active_record/type/helpers/mutable.rb6
-rw-r--r--activerecord/lib/active_record/type/helpers/numeric.rb2
-rw-r--r--activerecord/lib/active_record/type/integer.rb6
-rw-r--r--activerecord/lib/active_record/type/serialized.rb6
-rw-r--r--activerecord/lib/active_record/type/string.rb2
-rw-r--r--activerecord/lib/active_record/type/value.rb32
-rw-r--r--activerecord/lib/active_record/type_caster/map.rb2
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb2
-rw-r--r--activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb4
-rw-r--r--activerecord/test/cases/adapters/mysql/reserved_word_test.rb2
-rw-r--r--activerecord/test/cases/adapters/mysql/schema_test.rb2
-rw-r--r--activerecord/test/cases/adapters/mysql2/connection_test.rb2
-rw-r--r--activerecord/test/cases/adapters/mysql2/reserved_word_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb14
-rw-r--r--activerecord/test/cases/adapters/postgresql/bit_string_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/bytea_test.rb8
-rw-r--r--activerecord/test/cases/adapters/postgresql/cidr_test.rb6
-rw-r--r--activerecord/test/cases/adapters/postgresql/citext_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/composite_test.rb8
-rw-r--r--activerecord/test/cases/adapters/postgresql/connection_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/domain_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/enum_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/full_text_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/geometric_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/hstore_test.rb32
-rw-r--r--activerecord/test/cases/adapters/postgresql/infinity_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/integer_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/json_test.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/ltree_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/money_test.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/network_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/numbers_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/quoting_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/range_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/rename_table_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/type_lookup_test.rb8
-rw-r--r--activerecord/test/cases/adapters/postgresql/uuid_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/xml_test.rb2
-rw-r--r--activerecord/test/cases/adapters/sqlite3/quoting_test.rb2
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb4
-rw-r--r--activerecord/test/cases/attribute_decorators_test.rb8
-rw-r--r--activerecord/test/cases/attribute_set_test.rb4
-rw-r--r--activerecord/test/cases/attribute_test.rb32
-rw-r--r--activerecord/test/cases/attributes_test.rb4
-rw-r--r--activerecord/test/cases/base_test.rb2
-rw-r--r--activerecord/test/cases/batches_test.rb35
-rw-r--r--activerecord/test/cases/connection_adapters/type_lookup_test.rb2
-rw-r--r--activerecord/test/cases/date_time_precision_test.rb2
-rw-r--r--activerecord/test/cases/dirty_test.rb6
-rw-r--r--activerecord/test/cases/enum_test.rb53
-rw-r--r--activerecord/test/cases/migration/change_schema_test.rb4
-rw-r--r--activerecord/test/cases/migration/columns_test.rb6
-rw-r--r--activerecord/test/cases/migration/foreign_key_test.rb21
-rw-r--r--activerecord/test/cases/primary_keys_test.rb2
-rw-r--r--activerecord/test/cases/reflection_test.rb6
-rw-r--r--activerecord/test/cases/relation_test.rb4
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb2
-rw-r--r--activerecord/test/cases/secure_token_test.rb7
-rw-r--r--activerecord/test/cases/time_precision_test.rb65
-rw-r--r--activerecord/test/cases/transactions_test.rb2
-rw-r--r--activerecord/test/cases/type/adapter_specific_registry_test.rb133
-rw-r--r--activerecord/test/cases/type/decimal_test.rb16
-rw-r--r--activerecord/test/cases/type/integer_test.rb62
-rw-r--r--activerecord/test/cases/type/string_test.rb10
-rw-r--r--activerecord/test/cases/type/unsigned_integer_test.rb4
-rw-r--r--activerecord/test/cases/type_test.rb39
-rw-r--r--activerecord/test/cases/types_test.rb94
-rw-r--r--activerecord/test/migrations/missing/1000_people_have_middle_names.rb2
-rw-r--r--activerecord/test/migrations/missing/1_people_have_last_names.rb2
-rw-r--r--activerecord/test/migrations/missing/3_we_need_reminders.rb2
-rw-r--r--activerecord/test/migrations/missing/4_innocent_jointable.rb2
-rw-r--r--activerecord/test/migrations/rename/1_we_need_things.rb2
-rw-r--r--activerecord/test/migrations/rename/2_rename_things.rb2
-rw-r--r--activerecord/test/migrations/valid/2_we_need_reminders.rb2
-rw-r--r--activerecord/test/migrations/valid/3_innocent_jointable.rb2
-rw-r--r--activerecord/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb2
-rw-r--r--activerecord/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb2
-rw-r--r--activerecord/test/models/admin.rb2
-rw-r--r--activerecord/test/models/admin/account.rb2
-rw-r--r--activerecord/test/models/binary.rb2
-rw-r--r--activerecord/test/models/event.rb2
-rw-r--r--activerecord/test/models/guid.rb2
-rw-r--r--activerecord/test/models/pirate.rb2
-rw-r--r--activerecord/test/schema/postgresql_specific_schema.rb2
128 files changed, 931 insertions, 543 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index e1cace7d88..d0d5481d81 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,12 @@
+* Deprecated passing of `start` value to `find_in_batches` and `find_each`
+ in favour of `begin_at` value.
+
+ *Vipul A M*
+
+* Add `foreign_key_exists?` method.
+
+ *Tõnis Simo*
+
* Use SQL COUNT and LIMIT 1 queries for `none?` and `one?` methods if no block or limit is given,
instead of loading the entire collection to memory.
This applies to relations (e.g. `User.all`) as well as associations (e.g. `account.users`)
@@ -20,10 +29,6 @@
*Eugene Gilburg*
-* Allow `:precision` option for time type columns.
-
- *Ryuta Kamizono*
-
* Have `enum` perform type casting consistently with the rest of Active
Record, such as `where`.
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 5a3b4f0c40..a146d78a5a 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1386,7 +1386,7 @@ module ActiveRecord
# has_one :last_comment, -> { order 'posted_on' }, class_name: "Comment"
# has_one :project_manager, -> { where role: 'project_manager' }, class_name: "Person"
# has_one :attachment, as: :attachable
- # has_one :boss, readonly: :true
+ # has_one :boss, -> { readonly }
# has_one :club, through: :membership
# has_one :primary_address, -> { where primary: true }, through: :addressables, source: :addressable
# has_one :credit_card, required: true
@@ -1438,7 +1438,7 @@ module ActiveRecord
# when you access the associated object.
#
# Scope examples:
- # belongs_to :user, -> { where(id: 2) }
+ # belongs_to :firm, -> { where(id: 2) }
# belongs_to :user, -> { joins(:friends) }
# belongs_to :level, ->(level) { where("game_level > ?", level.current) }
#
@@ -1514,11 +1514,11 @@ module ActiveRecord
# belongs_to :valid_coupon, ->(o) { where "discounts > ?", o.payments_count },
# class_name: "Coupon", foreign_key: "coupon_id"
# belongs_to :attachable, polymorphic: true
- # belongs_to :project, readonly: true
+ # belongs_to :project, -> { readonly }
# belongs_to :post, counter_cache: true
- # belongs_to :company, touch: true
+ # belongs_to :comment, touch: true
# belongs_to :company, touch: :employees_last_updated_at
- # belongs_to :company, required: true
+ # belongs_to :user, required: true
def belongs_to(name, scope = nil, options = {})
reflection = Builder::BelongsTo.build(self, name, scope, options)
Reflection.add_reflection self, name, reflection
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 33e4516bd1..eea847cfa3 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -63,7 +63,7 @@ module ActiveRecord
def ids_writer(ids)
pk_type = reflection.primary_key_type
ids = Array(ids).reject(&:blank?)
- ids.map! { |i| pk_type.type_cast_from_user(i) }
+ ids.map! { |i| pk_type.cast(i) }
replace(klass.find(ids).index_by(&:id).values_at(*ids))
end
diff --git a/activerecord/lib/active_record/attribute.rb b/activerecord/lib/active_record/attribute.rb
index 91886f1324..73dd3fa041 100644
--- a/activerecord/lib/active_record/attribute.rb
+++ b/activerecord/lib/active_record/attribute.rb
@@ -43,7 +43,7 @@ module ActiveRecord
end
def value_for_database
- type.type_cast_for_database(value)
+ type.serialize(value)
end
def changed_from?(old_value)
@@ -108,13 +108,13 @@ module ActiveRecord
class FromDatabase < Attribute # :nodoc:
def type_cast(value)
- type.type_cast_from_database(value)
+ type.deserialize(value)
end
end
class FromUser < Attribute # :nodoc:
def type_cast(value)
- type.type_cast_from_user(value)
+ type.cast(value)
end
def came_from_user?
diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
index 90c36e4b02..f9beb43e4b 100644
--- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
+++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
@@ -2,13 +2,13 @@ module ActiveRecord
module AttributeMethods
module TimeZoneConversion
class TimeZoneConverter < DelegateClass(Type::Value) # :nodoc:
- def type_cast_from_database(value)
+ def deserialize(value)
convert_time_to_time_zone(super)
end
- def type_cast_from_user(value)
+ def cast(value)
if value.is_a?(Array)
- value.map { |v| type_cast_from_user(v) }
+ value.map { |v| cast(v) }
elsif value.is_a?(Hash)
set_time_zone_without_conversion(super)
elsif value.respond_to?(:in_time_zone)
diff --git a/activerecord/lib/active_record/attributes.rb b/activerecord/lib/active_record/attributes.rb
index 2c475f3cda..c8979a60d7 100644
--- a/activerecord/lib/active_record/attributes.rb
+++ b/activerecord/lib/active_record/attributes.rb
@@ -102,14 +102,14 @@ module ActiveRecord
#
# Users may also define their own custom types, as long as they respond
# to the methods defined on the value type. The method
- # +type_cast_from_database+ or +type_cast_from_user+ will be called on
+ # +deserialize+ or +cast+ will be called on
# your type object, with raw input from the database or from your
# controllers. See ActiveRecord::Type::Value for the expected API. It is
# recommended that your type objects inherit from an existing type, or
# from ActiveRecord::Type::Value
#
# class MoneyType < ActiveRecord::Type::Integer
- # def type_cast_from_user(value)
+ # def cast(value)
# if value.include?('$')
# price_in_dollars = value.gsub(/\$/, '').to_f
# super(price_in_dollars * 100)
@@ -119,21 +119,27 @@ module ActiveRecord
# end
# end
#
+ # # config/initializers/types.rb
+ # ActiveRecord::Type.register(:money, MoneyType)
+ #
+ # # /app/models/store_listing.rb
# class StoreListing < ActiveRecord::Base
- # attribute :price_in_cents, MoneyType.new
+ # attribute :price_in_cents, :money
# end
#
# store_listing = StoreListing.new(price_in_cents: '$10.00')
# store_listing.price_in_cents # => 1000
#
# For more details on creating custom types, see the documentation for
- # ActiveRecord::Type::Value.
+ # ActiveRecord::Type::Value. For more details on registering your types
+ # to be referenced by a symbol, see ActiveRecord::Type.register. You can
+ # also pass a type object directly, in place of a symbol.
#
# ==== Querying
#
# When ActiveRecord::QueryMethods#where is called, it will
# use the type defined by the model class to convert the value to SQL,
- # calling +type_cast_for_database+ on your type object. For example:
+ # calling +serialize+ on your type object. For example:
#
# class Money < Struct.new(:amount, :currency)
# end
@@ -143,18 +149,20 @@ module ActiveRecord
# @currency_converter = currency_converter
# end
#
- # # value will be the result of +type_cast_from_database+ or
- # # +type_cast_from_user+. Assumed to be in instance of +Money+ in
+ # # value will be the result of +deserialize+ or
+ # # +cast+. Assumed to be in instance of +Money+ in
# # this case.
- # def type_cast_for_database(value)
+ # def serialize(value)
# value_in_bitcoins = @currency_converter.convert_to_bitcoins(value)
# value_in_bitcoins.amount
# end
# end
#
+ # ActiveRecord::Type.register(:money, MoneyType)
+ #
# class Product < ActiveRecord::Base
# currency_converter = ConversionRatesFromTheInternet.new
- # attribute :price_in_bitcoins, MoneyType.new(currency_converter)
+ # attribute :price_in_bitcoins, :money, currency_converter
# end
#
# Product.where(price_in_bitcoins: Money.new(5, "USD"))
@@ -195,7 +203,7 @@ module ActiveRecord
# Otherwise, the default will be +nil+.
#
# +user_provided_default+ Whether the default value should be cast using
- # +type_cast_from_user+ or +type_cast_from_database+.
+ # +cast+ or +deserialize+.
def define_attribute(
name,
cast_type,
@@ -210,7 +218,7 @@ module ActiveRecord
super
attributes_to_define_after_schema_loads.each do |name, (type, options)|
if type.is_a?(Symbol)
- type = connection.type_for_attribute_options(type, **options.except(:default))
+ type = ActiveRecord::Type.lookup(type, **options.except(:default))
end
define_attribute(name, type, **options.slice(:default))
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
index 947e11c7bf..d2840b9498 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
@@ -52,7 +52,7 @@ module ActiveRecord
def type_cast_from_column(column, value) # :nodoc:
if column
type = lookup_cast_type_from_column(column)
- type.type_cast_for_database(value)
+ type.serialize(value)
else
value
end
@@ -103,7 +103,7 @@ module ActiveRecord
end
def quote_default_expression(value, column) #:nodoc:
- value = lookup_cast_type(column.sql_type).type_cast_for_database(value)
+ value = lookup_cast_type(column.sql_type).serialize(value)
quote(value)
end
@@ -144,29 +144,8 @@ module ActiveRecord
binds.map(&:value_for_database)
end
- def type_for_attribute_options(type_name, **options)
- klass = type_classes_with_standard_constructor.fetch(type_name, Type::Value)
- klass.new(**options)
- end
-
private
- def type_classes_with_standard_constructor
- {
- big_integer: Type::BigInteger,
- binary: Type::Binary,
- boolean: Type::Boolean,
- date: Type::Date,
- date_time: Type::DateTime,
- decimal: Type::Decimal,
- float: Type::Float,
- integer: Type::Integer,
- string: Type::String,
- text: Type::Text,
- time: Type::Time,
- }
- end
-
def types_which_need_no_typecasting
[nil, Numeric, String]
end
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 8cd4b8e5b2..a2777fcd0a 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -50,6 +50,14 @@ module ActiveRecord
options[:primary_key] != default_primary_key
end
+ def defined_for?(options_or_to_table = {})
+ if options_or_to_table.is_a?(Hash)
+ options_or_to_table.all? {|key, value| options[key].to_s == value.to_s }
+ else
+ to_table == options_or_to_table.to_s
+ end
+ end
+
private
def default_primary_key
"id"
@@ -651,6 +659,10 @@ module ActiveRecord
@base.add_foreign_key(name, *args)
end
+ def foreign_key_exists?(*args) # :nodoc:
+ @base.foreign_key_exists?(name, *args)
+ end
+
private
def native
@base.native_database_types
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
index 932aaf7aa7..af7ef7cbaa 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
@@ -47,7 +47,7 @@ module ActiveRecord
def schema_default(column)
type = lookup_cast_type_from_column(column)
- default = type.type_cast_from_database(column.default)
+ default = type.deserialize(column.default)
unless default.nil?
type.type_cast_for_schema(default)
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 c9180f64db..503b09d1fc 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -667,7 +667,7 @@ module ActiveRecord
# remove_reference(:products, :user, index: true, foreign_key: true)
#
def remove_reference(table_name, ref_name, options = {})
- remove_foreign_key table_name, ref_name if options[:foreign_key]
+ remove_foreign_key table_name, ref_name.to_s.pluralize if options[:foreign_key]
remove_column(table_name, "#{ref_name}_id")
remove_column(table_name, "#{ref_name}_type") if options[:polymorphic]
@@ -757,21 +757,7 @@ module ActiveRecord
def remove_foreign_key(from_table, options_or_to_table = {})
return unless supports_foreign_keys?
- if options_or_to_table.is_a?(Hash)
- options = options_or_to_table
- else
- options = { column: foreign_key_column_for(options_or_to_table) }
- end
-
- fk_name_to_delete = options.fetch(:name) do
- fk_to_delete = foreign_keys(from_table).detect {|fk| fk.column == options[:column].to_s }
-
- if fk_to_delete
- fk_to_delete.name
- else
- raise ArgumentError, "Table '#{from_table}' has no foreign key on column '#{options[:column]}'"
- end
- end
+ fk_name_to_delete = foreign_key_for!(from_table, options_or_to_table).name
at = create_alter_table from_table
at.drop_foreign_key fk_name_to_delete
@@ -779,6 +765,31 @@ module ActiveRecord
execute schema_creation.accept(at)
end
+ # Checks to see if a foreign key exists on a table for a given foreign key definition.
+ #
+ # # Check a foreign key exists
+ # foreign_key_exists?(:accounts, :branches)
+ #
+ # # Check a foreign key on specified column exists
+ # foreign_key_exists?(:accounts, column: :owner_id)
+ #
+ # # Check a foreign key with a custom name exists
+ # foreign_key_exists?(:accounts, name: "special_fk_name")
+ #
+ def foreign_key_exists?(from_table, options_or_to_table = {})
+ foreign_key_for(from_table, options_or_to_table).present?
+ end
+
+ def foreign_key_for(from_table, options_or_to_table = {}) # :nodoc:
+ return unless supports_foreign_keys?
+ foreign_keys(from_table).detect {|fk| fk.defined_for? options_or_to_table }
+ end
+
+ def foreign_key_for!(from_table, options_or_to_table = {}) # :nodoc:
+ foreign_key_for(from_table, options_or_to_table) or \
+ raise ArgumentError, "Table '#{from_table}' has no foreign key for #{options_or_to_table}"
+ end
+
def foreign_key_column_for(table_name) # :nodoc:
"#{table_name.to_s.singularize}_id"
end
@@ -840,12 +851,6 @@ module ActiveRecord
raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
end
- elsif [:datetime, :time].include?(type) && precision ||= native[:precision]
- if (0..6) === precision
- column_type_sql << "(#{precision})"
- else
- raise(ActiveRecordError, "No #{native[:name]} type has precision of #{precision}. The allowed range of precision is from 0 to 6")
- end
elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
column_type_sql << "(#{limit})"
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index c307189980..ee11c0efa4 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -245,11 +245,6 @@ module ActiveRecord
false
end
- # Does this adapter support datetime with precision?
- def supports_datetime_with_precision?
- false
- end
-
# This is meant to be implemented by the adapters that support extensions
def disable_extension(name)
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 0a9e599c3c..0a1c66be1e 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -251,10 +251,6 @@ module ActiveRecord
version[0] >= 5
end
- def supports_datetime_with_precision?
- (version[0] == 5 && version[1] >= 6) || version[0] >= 6
- end
-
def native_database_types
NATIVE_DATABASE_TYPES
end
@@ -627,6 +623,13 @@ module ActiveRecord
when 0x1000000..0xffffffff; 'longtext'
else raise(ActiveRecordError, "No text type has character length #{limit}")
end
+ when 'datetime'
+ return super unless precision
+
+ case precision
+ when 0..6; "datetime(#{precision})"
+ else raise(ActiveRecordError, "No datetime type has precision of #{precision}. The allowed range of precision is from 0 to 6.")
+ end
else
super
end
@@ -923,7 +926,7 @@ module ActiveRecord
end
class MysqlString < Type::String # :nodoc:
- def type_cast_for_database(value)
+ def serialize(value)
case value
when true then "1"
when false then "0"
@@ -942,9 +945,8 @@ module ActiveRecord
end
end
- def type_classes_with_standard_constructor
- super.merge(string: MysqlString)
- end
+ ActiveRecord::Type.register(:string, MysqlString, adapter: :mysql)
+ ActiveRecord::Type.register(:string, MysqlString, adapter: :mysql2)
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
index 2608a2abab..fb4e0de2a8 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
@@ -25,22 +25,22 @@ module ActiveRecord
@delimiter = delimiter
end
- def type_cast_from_database(value)
+ def deserialize(value)
if value.is_a?(::String)
- type_cast_array(parse_pg_array(value), :type_cast_from_database)
+ type_cast_array(parse_pg_array(value), :deserialize)
else
super
end
end
- def type_cast_from_user(value)
+ def cast(value)
if value.is_a?(::String)
value = parse_pg_array(value)
end
- type_cast_array(value, :type_cast_from_user)
+ type_cast_array(value, :cast)
end
- def type_cast_for_database(value)
+ def serialize(value)
if value.is_a?(::Array)
cast_value_for_database(value)
else
@@ -69,7 +69,7 @@ module ActiveRecord
casted_values = value.map { |item| cast_value_for_database(item) }
"{#{casted_values.join(delimiter)}}"
else
- quote_and_escape(subtype.type_cast_for_database(value))
+ quote_and_escape(subtype.serialize(value))
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb
index 1dbb40ca1d..ea0fa2517f 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb
@@ -7,7 +7,7 @@ module ActiveRecord
:bit
end
- def type_cast(value)
+ def cast(value)
if ::String === value
case value
when /^0x/i
@@ -20,7 +20,7 @@ module ActiveRecord
end
end
- def type_cast_for_database(value)
+ def serialize(value)
Data.new(super) if value
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea.rb
index 6bd1b8ecae..8f9d6e7f9b 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea.rb
@@ -3,7 +3,7 @@ module ActiveRecord
module PostgreSQL
module OID # :nodoc:
class Bytea < Type::Binary # :nodoc:
- def type_cast_from_database(value)
+ def deserialize(value)
return if value.nil?
return value.to_s if value.is_a?(Type::Binary::Data)
PGconn.unescape_bytea(super)
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr.rb
index 222f10fa8f..eeccb09bdf 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr.rb
@@ -18,7 +18,7 @@ module ActiveRecord
end
end
- def type_cast_for_database(value)
+ def serialize(value)
if IPAddr === value
"#{value}/#{value.instance_variable_get(:@mask_addr).to_s(2).count('1')}"
else
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum.rb
index 77d5038efd..b3b610a5f6 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum.rb
@@ -7,7 +7,7 @@ module ActiveRecord
:enum
end
- def type_cast(value)
+ def cast(value)
value.to_s
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb
index b46e50c865..9270fc9f21 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb
@@ -9,7 +9,7 @@ module ActiveRecord
:hstore
end
- def type_cast_from_database(value)
+ def deserialize(value)
if value.is_a?(::String)
::Hash[value.scan(HstorePair).map { |k, v|
v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
@@ -21,7 +21,7 @@ module ActiveRecord
end
end
- def type_cast_for_database(value)
+ def serialize(value)
if value.is_a?(::Hash)
value.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(', ')
else
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb
index 13dd037314..8e1256baad 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb
@@ -9,19 +9,19 @@ module ActiveRecord
:json
end
- def type_cast_from_database(value)
+ def deserialize(value)
if value.is_a?(::String)
::ActiveSupport::JSON.decode(value) rescue nil
else
- super
+ value
end
end
- def type_cast_for_database(value)
+ def serialize(value)
if value.is_a?(::Array) || value.is_a?(::Hash)
::ActiveSupport::JSON.encode(value)
else
- super
+ value
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
index 380c50fc14..afc9383f91 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
@@ -13,7 +13,7 @@ module ActiveRecord
# the comparison here. Therefore, we need to parse and re-dump the
# raw value here to ensure the insignificant whitespaces are
# consistent with our encoder's output.
- raw_old_value = type_cast_for_database(type_cast_from_database(raw_old_value))
+ raw_old_value = serialize(deserialize(raw_old_value))
super(raw_old_value, new_value)
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb
index 4084725ed7..bf565bcf47 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb
@@ -9,13 +9,13 @@ module ActiveRecord
:point
end
- def type_cast(value)
+ def cast(value)
case value
when ::String
if value[0] == '(' && value[-1] == ')'
value = value[1...-1]
end
- type_cast(value.split(','))
+ cast(value.split(','))
when ::Array
value.map { |v| Float(v) }
else
@@ -23,7 +23,7 @@ module ActiveRecord
end
end
- def type_cast_for_database(value)
+ def serialize(value)
if value.is_a?(::Array)
"(#{number_for_point(value[0])},#{number_for_point(value[1])})"
else
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/range.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/range.rb
index 9d3633d109..fc201f8fb9 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/range.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/range.rb
@@ -30,7 +30,7 @@ module ActiveRecord
::Range.new(from, to, extracted[:exclude_end])
end
- def type_cast_for_database(value)
+ def serialize(value)
if value.is_a?(::Range)
from = type_cast_single_for_database(value.begin)
to = type_cast_single_for_database(value.end)
@@ -49,11 +49,11 @@ module ActiveRecord
private
def type_cast_single(value)
- infinity?(value) ? value : @subtype.type_cast_from_database(value)
+ infinity?(value) ? value : @subtype.deserialize(value)
end
def type_cast_single_for_database(value)
- infinity?(value) ? '' : @subtype.type_cast_for_database(value)
+ infinity?(value) ? '' : @subtype.serialize(value)
end
def extract_bounds(value)
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid.rb
index 97b4fd3d08..5e839228e9 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid.rb
@@ -5,13 +5,13 @@ module ActiveRecord
class Uuid < Type::Value # :nodoc:
ACCEPTABLE_UUID = %r{\A\{?([a-fA-F0-9]{4}-?){8}\}?\z}x
- alias_method :type_cast_for_database, :type_cast_from_database
+ alias_method :serialize, :deserialize
def type
:uuid
end
- def type_cast(value)
+ def cast(value)
value.to_s[ACCEPTABLE_UUID, 0]
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector.rb
index de4187b028..b26e876b54 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector.rb
@@ -16,7 +16,7 @@ module ActiveRecord
# FIXME: this should probably split on +delim+ and use +subtype+
# to cast the values. Unfortunately, the current Rails behavior
# is to just return the string.
- def type_cast(value)
+ def cast(value)
value
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml.rb
index 334af7c598..d40d837cee 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml.rb
@@ -7,7 +7,7 @@ module ActiveRecord
:xml
end
- def type_cast_for_database(value)
+ def serialize(value)
return unless value
Data.new(super)
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
index b8d0e26f85..b7755c4593 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
@@ -67,23 +67,6 @@ module ActiveRecord
type_map.lookup(column.oid, column.fmod, column.sql_type)
end
- def type_for_attribute_options(
- type_name,
- array: false,
- range: false,
- **options
- )
- if array
- subtype = type_for_attribute_options(type_name, **options)
- OID::Array.new(subtype)
- elsif range
- subtype = type_for_attribute_options(type_name, **options)
- OID::Range.new(subtype)
- else
- super(type_name, **options)
- end
- end
-
private
def _quote(value)
@@ -122,27 +105,6 @@ module ActiveRecord
super
end
end
-
- def type_classes_with_standard_constructor
- super.merge(
- bit: OID::Bit,
- bit_varying: OID::BitVarying,
- binary: OID::Bytea,
- cidr: OID::Cidr,
- date_time: OID::DateTime,
- decimal: OID::Decimal,
- enum: OID::Enum,
- hstore: OID::Hstore,
- inet: OID::Inet,
- json: OID::Json,
- jsonb: OID::Jsonb,
- money: OID::Money,
- point: OID::Point,
- uuid: OID::Uuid,
- vector: OID::Vector,
- xml: OID::Xml,
- )
- end
end
end
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 503dda60f4..81fde18f64 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -534,6 +534,13 @@ module ActiveRecord
when 5..8; 'bigint'
else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.")
end
+ when 'datetime'
+ return super unless precision
+
+ case precision
+ when 0..6; "timestamp(#{precision})"
+ else raise(ActiveRecordError, "No timestamp type has precision of #{precision}. The allowed range of precision is from 0 to 6")
+ end
else
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 6d7e1075d7..5a887ea529 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -180,10 +180,6 @@ module ActiveRecord
true
end
- def supports_datetime_with_precision?
- true
- end
-
def index_algorithms
{ concurrently: 'CONCURRENTLY' }
end
@@ -481,6 +477,7 @@ module ActiveRecord
register_class_with_limit m, 'varbit', OID::BitVarying
m.alias_type 'timestamptz', 'timestamp'
m.register_type 'date', Type::Date.new
+ m.register_type 'time', Type::Time.new
m.register_type 'money', OID::Money.new
m.register_type 'bytea', OID::Bytea.new
@@ -506,8 +503,10 @@ module ActiveRecord
m.alias_type 'lseg', 'varchar'
m.alias_type 'box', 'varchar'
- register_class_with_precision m, 'time', Type::Time
- register_class_with_precision m, 'timestamp', OID::DateTime
+ m.register_type 'timestamp' do |_, _, sql_type|
+ precision = extract_precision(sql_type)
+ OID::DateTime.new(precision: precision)
+ end
m.register_type 'numeric' do |_, fmod, sql_type|
precision = extract_precision(sql_type)
@@ -813,6 +812,25 @@ module ActiveRecord
return unless coder_class
coder_class.new(oid: row['oid'], name: row['typname'])
end
+
+ ActiveRecord::Type.add_modifier({ array: true }, OID::Array, adapter: :postgresql)
+ ActiveRecord::Type.add_modifier({ range: true }, OID::Range, adapter: :postgresql)
+ ActiveRecord::Type.register(:bit, OID::Bit, adapter: :postgresql)
+ ActiveRecord::Type.register(:bit_varying, OID::BitVarying, adapter: :postgresql)
+ ActiveRecord::Type.register(:binary, OID::Bytea, adapter: :postgresql)
+ ActiveRecord::Type.register(:cidr, OID::Cidr, adapter: :postgresql)
+ ActiveRecord::Type.register(:date_time, OID::DateTime, adapter: :postgresql)
+ ActiveRecord::Type.register(:decimal, OID::Decimal, adapter: :postgresql)
+ ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
+ ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
+ ActiveRecord::Type.register(:inet, OID::Inet, adapter: :postgresql)
+ ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
+ ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
+ ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
+ ActiveRecord::Type.register(:point, OID::Point, adapter: :postgresql)
+ ActiveRecord::Type.register(:uuid, OID::Uuid, adapter: :postgresql)
+ ActiveRecord::Type.register(:vector, OID::Vector, adapter: :postgresql)
+ ActiveRecord::Type.register(:xml, OID::Xml, adapter: :postgresql)
end
end
end
diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb
index 3086f13f96..ea88983917 100644
--- a/activerecord/lib/active_record/enum.rb
+++ b/activerecord/lib/active_record/enum.rb
@@ -32,6 +32,12 @@ module ActiveRecord
# Conversation.active
# Conversation.archived
#
+ # Of course, you can also query them directly if the scopes doesn't fit your
+ # needs:
+ #
+ # Conversation.where(status: [:active, :archived])
+ # Conversation.where.not(status: :active)
+ #
# You can set the default value from the database declaration, like:
#
# create_table :conversations do |t|
@@ -59,15 +65,17 @@ module ActiveRecord
#
# In rare circumstances you might need to access the mapping directly.
# The mappings are exposed through a class method with the pluralized attribute
- # name:
+ # name, which return the mapping in a +HashWithIndifferentAccess+:
#
- # Conversation.statuses # => { "active" => 0, "archived" => 1 }
+ # Conversation.statuses[:active] # => 0
+ # Conversation.statuses["archived"] # => 1
#
- # Use that class method when you need to know the ordinal value of an enum:
+ # Use that class method when you need to know the ordinal value of an enum.
+ # For example, you can use that when manually building SQL strings:
#
# Conversation.where("status <> ?", Conversation.statuses[:archived])
#
- # Where conditions on an enum attribute must use the ordinal value of an enum.
+
module Enum
def self.extended(base) # :nodoc:
base.class_attribute(:defined_enums)
@@ -85,7 +93,7 @@ module ActiveRecord
@mapping = mapping
end
- def type_cast_from_user(value)
+ def cast(value)
return if value.blank?
if mapping.has_key?(value)
@@ -97,11 +105,12 @@ module ActiveRecord
end
end
- def type_cast_from_database(value)
+ def deserialize(value)
+ return if value.nil?
mapping.key(value.to_i)
end
- def type_cast_for_database(value)
+ def serialize(value)
mapping.fetch(value, value)
end
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index c5b10fcddf..a58d8355aa 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -185,7 +185,7 @@ module ActiveRecord
end
class LockingType < DelegateClass(Type::Value) # :nodoc:
- def type_cast_from_database(value)
+ def deserialize(value)
# `nil` *should* be changed to 0
super.to_i
end
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index 117a128579..084ef397a8 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -521,7 +521,7 @@ module ActiveRecord
# Determines if a hash contains a truthy _destroy key.
def has_destroy_flag?(hash)
- Type::Boolean.new.type_cast_from_user(hash['_destroy'])
+ Type::Boolean.new.cast(hash['_destroy'])
end
# Determines if a new record should be rejected by checking
diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb
index a543341149..e07580a563 100644
--- a/activerecord/lib/active_record/relation/batches.rb
+++ b/activerecord/lib/active_record/relation/batches.rb
@@ -27,15 +27,15 @@ module ActiveRecord
#
# ==== Options
# * <tt>:batch_size</tt> - Specifies the size of the batch. Default to 1000.
- # * <tt>:start</tt> - Specifies the primary key value to start from, inclusive of the value.
+ # * <tt>:begin_at</tt> - Specifies the primary key value to start from, inclusive of the value.
# * <tt>:end_at</tt> - Specifies the primary key value to end at, inclusive of the value.
# This is especially useful if you want multiple workers dealing with
# the same processing queue. You can make worker 1 handle all the records
# between id 0 and 10,000 and worker 2 handle from 10,000 and beyond
- # (by setting the +:start+ and +:end_at+ option on each worker).
+ # (by setting the +:begin_at+ and +:end_at+ option on each worker).
#
# # Let's process for a batch of 2000 records, skipping the first 2000 rows
- # Person.find_each(start: 2000, batch_size: 2000) do |person|
+ # Person.find_each(begin_at: 2000, batch_size: 2000) do |person|
# person.party_all_night!
# end
#
@@ -46,15 +46,22 @@ module ActiveRecord
#
# NOTE: You can't set the limit either, that's used to control
# the batch sizes.
- def find_each(start: nil, end_at: nil, batch_size: 1000)
+ def find_each(begin_at: nil, end_at: nil, batch_size: 1000, start: nil)
+ if start
+ begin_at = start
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ Passing `start` value to find_each is deprecated, and will be removed in Rails 5.1.
+ Please pass `begin_at` instead.
+ MSG
+ end
if block_given?
- find_in_batches(start: start, end_at: end_at, batch_size: batch_size) do |records|
+ find_in_batches(begin_at: begin_at, end_at: end_at, batch_size: batch_size) do |records|
records.each { |record| yield record }
end
else
- enum_for(:find_each, start: start, end_at: end_at, batch_size: batch_size) do
+ enum_for(:find_each, begin_at: begin_at, end_at: end_at, batch_size: batch_size) do
relation = self
- apply_limits(relation, start, end_at).size
+ apply_limits(relation, begin_at, end_at).size
end
end
end
@@ -79,15 +86,15 @@ module ActiveRecord
#
# ==== Options
# * <tt>:batch_size</tt> - Specifies the size of the batch. Default to 1000.
- # * <tt>:start</tt> - Specifies the primary key value to start from, inclusive of the value.
+ # * <tt>:begin_at</tt> - Specifies the primary key value to start from, inclusive of the value.
# * <tt>:end_at</tt> - Specifies the primary key value to end at, inclusive of the value.
# This is especially useful if you want multiple workers dealing with
# the same processing queue. You can make worker 1 handle all the records
# between id 0 and 10,000 and worker 2 handle from 10,000 and beyond
- # (by setting the +:start+ and +:end_at+ option on each worker).
+ # (by setting the +:begin_at+ and +:end_at+ option on each worker).
#
# # Let's process the next 2000 records
- # Person.find_in_batches(start: 2000, batch_size: 2000) do |group|
+ # Person.find_in_batches(begin_at: 2000, batch_size: 2000) do |group|
# group.each { |person| person.party_all_night! }
# end
#
@@ -98,12 +105,19 @@ module ActiveRecord
#
# NOTE: You can't set the limit either, that's used to control
# the batch sizes.
- def find_in_batches(start: nil, end_at: nil, batch_size: 1000)
- relation = self
+ def find_in_batches(begin_at: nil, end_at: nil, batch_size: 1000, start: nil)
+ if start
+ begin_at = start
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ Passing `start` value to find_in_batches is deprecated, and will be removed in Rails 5.1.
+ Please pass `begin_at` instead.
+ MSG
+ end
+ relation = self
unless block_given?
- return to_enum(:find_in_batches, start: start, end_at: end_at, batch_size: batch_size) do
- total = apply_limits(relation, start, end_at).size
+ return to_enum(:find_in_batches, begin_at: begin_at, end_at: end_at, batch_size: batch_size) do
+ total = apply_limits(relation, begin_at, end_at).size
(total - 1).div(batch_size) + 1
end
end
@@ -113,7 +127,7 @@ module ActiveRecord
end
relation = relation.reorder(batch_order).limit(batch_size)
- relation = apply_limits(relation, start, end_at)
+ relation = apply_limits(relation, begin_at, end_at)
records = relation.to_a
while records.any?
@@ -131,8 +145,8 @@ module ActiveRecord
private
- def apply_limits(relation, start, end_at)
- relation = relation.where(table[primary_key].gteq(start)) if start
+ def apply_limits(relation, begin_at, end_at)
+ relation = relation.where(table[primary_key].gteq(begin_at)) if begin_at
relation = relation.where(table[primary_key].lteq(end_at)) if end_at
relation
end
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index 63e0d2fc21..4a4de86d48 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -353,9 +353,9 @@ module ActiveRecord
def type_cast_calculated_value(value, type, operation = nil)
case operation
when 'count' then value.to_i
- when 'sum' then type.type_cast_from_database(value || 0)
+ when 'sum' then type.deserialize(value || 0)
when 'average' then value.respond_to?(:to_d) ? value.to_d : value
- else type.type_cast_from_database(value)
+ else type.deserialize(value)
end
end
diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb
index 3a3e65ef32..500c478e65 100644
--- a/activerecord/lib/active_record/result.rb
+++ b/activerecord/lib/active_record/result.rb
@@ -81,7 +81,7 @@ module ActiveRecord
def cast_values(type_overrides = {}) # :nodoc:
types = columns.map { |name| column_type(name, type_overrides) }
result = rows.map do |values|
- types.zip(values).map { |type, value| type.type_cast_from_database(value) }
+ types.zip(values).map { |type, value| type.deserialize(value) }
end
columns.one? ? result.map!(&:first) : result
diff --git a/activerecord/lib/active_record/sanitization.rb b/activerecord/lib/active_record/sanitization.rb
index 313e767dcb..c7f55ebaa1 100644
--- a/activerecord/lib/active_record/sanitization.rb
+++ b/activerecord/lib/active_record/sanitization.rb
@@ -75,7 +75,7 @@ module ActiveRecord
def sanitize_sql_hash_for_assignment(attrs, table)
c = connection
attrs.map do |attr, value|
- value = type_for_attribute(attr.to_s).type_cast_for_database(value)
+ value = type_for_attribute(attr.to_s).serialize(value)
"#{c.quote_table_name_for_assignment(table, attr)} = #{c.quote(value)}"
end.join(', ')
end
diff --git a/activerecord/lib/active_record/secure_token.rb b/activerecord/lib/active_record/secure_token.rb
index 07031b6371..0990f815a7 100644
--- a/activerecord/lib/active_record/secure_token.rb
+++ b/activerecord/lib/active_record/secure_token.rb
@@ -27,7 +27,7 @@ module ActiveRecord
# Load securerandom only when has_secure_token is used.
require 'active_support/core_ext/securerandom'
define_method("regenerate_#{attribute}") { update! attribute => self.class.generate_unique_secure_token }
- before_create { self.send("#{attribute}=", self.class.generate_unique_secure_token) }
+ before_create { self.send("#{attribute}=", self.class.generate_unique_secure_token) unless self.send("#{attribute}?")}
end
def generate_unique_secure_token
@@ -36,4 +36,3 @@ module ActiveRecord
end
end
end
-
diff --git a/activerecord/lib/active_record/type.rb b/activerecord/lib/active_record/type.rb
index f18b076d58..2c0cda69d0 100644
--- a/activerecord/lib/active_record/type.rb
+++ b/activerecord/lib/active_record/type.rb
@@ -16,5 +16,51 @@ require 'active_record/type/text'
require 'active_record/type/time'
require 'active_record/type/unsigned_integer'
+require 'active_record/type/adapter_specific_registry'
require 'active_record/type/type_map'
require 'active_record/type/hash_lookup_type_map'
+
+module ActiveRecord
+ module Type
+ @registry = AdapterSpecificRegistry.new
+
+ class << self
+ attr_accessor :registry # :nodoc:
+ delegate :add_modifier, to: :registry
+
+ # Add a new type to the registry, allowing it to be referenced as a
+ # symbol by ActiveRecord::Attributes::ClassMethods#attribute. If your
+ # type is only meant to be used with a specific database adapter, you can
+ # do so by passing +adapter: :postgresql+. If your type has the same
+ # name as a native type for the current adapter, an exception will be
+ # raised unless you specify an +:override+ option. +override: true+ will
+ # cause your type to be used instead of the native type. +override:
+ # false+ will cause the native type to be used over yours if one exists.
+ def register(type_name, klass = nil, **options, &block)
+ registry.register(type_name, klass, **options, &block)
+ end
+
+ def lookup(*args, adapter: current_adapter_name, **kwargs) # :nodoc:
+ registry.lookup(*args, adapter: adapter, **kwargs)
+ end
+
+ private
+
+ def current_adapter_name
+ ActiveRecord::Base.connection.adapter_name.downcase.to_sym
+ end
+ end
+
+ register(:big_integer, Type::BigInteger, override: false)
+ register(:binary, Type::Binary, override: false)
+ register(:boolean, Type::Boolean, override: false)
+ register(:date, Type::Date, override: false)
+ register(:date_time, Type::DateTime, override: false)
+ register(:decimal, Type::Decimal, override: false)
+ register(:float, Type::Float, override: false)
+ register(:integer, Type::Integer, override: false)
+ register(:string, Type::String, override: false)
+ register(:text, Type::Text, override: false)
+ register(:time, Type::Time, override: false)
+ end
+end
diff --git a/activerecord/lib/active_record/type/adapter_specific_registry.rb b/activerecord/lib/active_record/type/adapter_specific_registry.rb
new file mode 100644
index 0000000000..5f71b3cb94
--- /dev/null
+++ b/activerecord/lib/active_record/type/adapter_specific_registry.rb
@@ -0,0 +1,142 @@
+module ActiveRecord
+ # :stopdoc:
+ module Type
+ class AdapterSpecificRegistry
+ def initialize
+ @registrations = []
+ end
+
+ def register(type_name, klass = nil, **options, &block)
+ block ||= proc { |_, *args| klass.new(*args) }
+ registrations << Registration.new(type_name, block, **options)
+ end
+
+ def lookup(symbol, *args)
+ registration = registrations
+ .select { |r| r.matches?(symbol, *args) }
+ .max
+
+ if registration
+ registration.call(self, symbol, *args)
+ else
+ raise ArgumentError, "Unknown type #{symbol.inspect}"
+ end
+ end
+
+ def add_modifier(options, klass, **args)
+ registrations << DecorationRegistration.new(options, klass, **args)
+ end
+
+ protected
+
+ attr_reader :registrations
+ end
+
+ class Registration
+ def initialize(name, block, adapter: nil, override: nil)
+ @name = name
+ @block = block
+ @adapter = adapter
+ @override = override
+ end
+
+ def call(_registry, *args, adapter: nil, **kwargs)
+ if kwargs.any? # https://bugs.ruby-lang.org/issues/10856
+ block.call(*args, **kwargs)
+ else
+ block.call(*args)
+ end
+ end
+
+ def matches?(type_name, *args, **kwargs)
+ type_name == name && matches_adapter?(**kwargs)
+ end
+
+ def <=>(other)
+ if conflicts_with?(other)
+ raise TypeConflictError.new("Type #{name} was registered for all
+ adapters, but shadows a native type with
+ the same name for #{other.adapter}".squish)
+ end
+ priority <=> other.priority
+ end
+
+ protected
+
+ attr_reader :name, :block, :adapter, :override
+
+ def priority
+ result = 0
+ if adapter
+ result |= 1
+ end
+ if override
+ result |= 2
+ end
+ result
+ end
+
+ def priority_except_adapter
+ priority & 0b111111100
+ end
+
+ private
+
+ def matches_adapter?(adapter: nil, **)
+ (self.adapter.nil? || adapter == self.adapter)
+ end
+
+ def conflicts_with?(other)
+ same_priority_except_adapter?(other) &&
+ has_adapter_conflict?(other)
+ end
+
+ def same_priority_except_adapter?(other)
+ priority_except_adapter == other.priority_except_adapter
+ end
+
+ def has_adapter_conflict?(other)
+ (override.nil? && other.adapter) ||
+ (adapter && other.override.nil?)
+ end
+ end
+
+ class DecorationRegistration < Registration
+ def initialize(options, klass, adapter: nil)
+ @options = options
+ @klass = klass
+ @adapter = adapter
+ end
+
+ def call(registry, *args, **kwargs)
+ subtype = registry.lookup(*args, **kwargs.except(*options.keys))
+ klass.new(subtype)
+ end
+
+ def matches?(*args, **kwargs)
+ matches_adapter?(**kwargs) && matches_options?(**kwargs)
+ end
+
+ def priority
+ super | 4
+ end
+
+ protected
+
+ attr_reader :options, :klass
+
+ private
+
+ def matches_options?(**kwargs)
+ options.all? do |key, value|
+ kwargs[key] == value
+ end
+ end
+ end
+ end
+
+ class TypeConflictError < StandardError
+ end
+
+ # :startdoc:
+end
diff --git a/activerecord/lib/active_record/type/binary.rb b/activerecord/lib/active_record/type/binary.rb
index 005a48ef0d..0baf8c63ad 100644
--- a/activerecord/lib/active_record/type/binary.rb
+++ b/activerecord/lib/active_record/type/binary.rb
@@ -9,7 +9,7 @@ module ActiveRecord
true
end
- def type_cast(value)
+ def cast(value)
if value.is_a?(Data)
value.to_s
else
@@ -17,13 +17,13 @@ module ActiveRecord
end
end
- def type_cast_for_database(value)
+ def serialize(value)
return if value.nil?
Data.new(super)
end
def changed_in_place?(raw_old_value, value)
- old_value = type_cast_from_database(raw_old_value)
+ old_value = deserialize(raw_old_value)
old_value != value
end
diff --git a/activerecord/lib/active_record/type/date_time.rb b/activerecord/lib/active_record/type/date_time.rb
index a25f2521bb..05d2af3808 100644
--- a/activerecord/lib/active_record/type/date_time.rb
+++ b/activerecord/lib/active_record/type/date_time.rb
@@ -10,7 +10,7 @@ module ActiveRecord
:datetime
end
- def type_cast_for_database(value)
+ def serialize(value)
if precision && value.respond_to?(:usec)
number_of_insignificant_digits = 6 - precision
round_power = 10 ** number_of_insignificant_digits
diff --git a/activerecord/lib/active_record/type/float.rb b/activerecord/lib/active_record/type/float.rb
index b3928242b7..d88482b85d 100644
--- a/activerecord/lib/active_record/type/float.rb
+++ b/activerecord/lib/active_record/type/float.rb
@@ -7,7 +7,7 @@ module ActiveRecord
:float
end
- alias type_cast_for_database type_cast
+ alias serialize cast
private
diff --git a/activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb b/activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb
index 640943c5e9..be571fc1c7 100644
--- a/activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb
+++ b/activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb
@@ -3,7 +3,7 @@ module ActiveRecord
module Helpers
class AcceptsMultiparameterTime < Module # :nodoc:
def initialize(defaults: {})
- define_method(:type_cast_from_user) do |value|
+ define_method(:cast) do |value|
if value.is_a?(Hash)
value_from_multiparameter_assignment(value)
else
diff --git a/activerecord/lib/active_record/type/helpers/mutable.rb b/activerecord/lib/active_record/type/helpers/mutable.rb
index dc37f4a885..88a9099277 100644
--- a/activerecord/lib/active_record/type/helpers/mutable.rb
+++ b/activerecord/lib/active_record/type/helpers/mutable.rb
@@ -2,15 +2,15 @@ module ActiveRecord
module Type
module Helpers
module Mutable # :nodoc:
- def type_cast_from_user(value)
- type_cast_from_database(type_cast_for_database(value))
+ def cast(value)
+ deserialize(serialize(value))
end
# +raw_old_value+ will be the `_before_type_cast` version of the
# value (likely a string). +new_value+ will be the current, type
# cast value.
def changed_in_place?(raw_old_value, new_value)
- raw_old_value != type_cast_for_database(new_value)
+ raw_old_value != serialize(new_value)
end
end
end
diff --git a/activerecord/lib/active_record/type/helpers/numeric.rb b/activerecord/lib/active_record/type/helpers/numeric.rb
index b0d4f03117..a755a02a59 100644
--- a/activerecord/lib/active_record/type/helpers/numeric.rb
+++ b/activerecord/lib/active_record/type/helpers/numeric.rb
@@ -2,7 +2,7 @@ module ActiveRecord
module Type
module Helpers
module Numeric # :nodoc:
- def type_cast(value)
+ def cast(value)
value = case value
when true then 1
when false then 0
diff --git a/activerecord/lib/active_record/type/integer.rb b/activerecord/lib/active_record/type/integer.rb
index 2ab2402dfd..2a1b04ac7f 100644
--- a/activerecord/lib/active_record/type/integer.rb
+++ b/activerecord/lib/active_record/type/integer.rb
@@ -16,13 +16,13 @@ module ActiveRecord
:integer
end
- def type_cast_from_database(value)
+ def deserialize(value)
return if value.nil?
value.to_i
end
- def type_cast_for_database(value)
- result = type_cast(value)
+ def serialize(value)
+ result = cast(value)
if result
ensure_in_range(result)
end
diff --git a/activerecord/lib/active_record/type/serialized.rb b/activerecord/lib/active_record/type/serialized.rb
index 6c6c520048..732029c723 100644
--- a/activerecord/lib/active_record/type/serialized.rb
+++ b/activerecord/lib/active_record/type/serialized.rb
@@ -11,7 +11,7 @@ module ActiveRecord
super(subtype)
end
- def type_cast_from_database(value)
+ def deserialize(value)
if default_value?(value)
value
else
@@ -19,7 +19,7 @@ module ActiveRecord
end
end
- def type_cast_for_database(value)
+ def serialize(value)
return if value.nil?
unless default_value?(value)
super coder.dump(value)
@@ -28,7 +28,7 @@ module ActiveRecord
def changed_in_place?(raw_old_value, value)
return false if value.nil?
- subtype.changed_in_place?(raw_old_value, type_cast_for_database(value))
+ subtype.changed_in_place?(raw_old_value, serialize(value))
end
def accessor
diff --git a/activerecord/lib/active_record/type/string.rb b/activerecord/lib/active_record/type/string.rb
index fbc0af2c5a..2662b7e874 100644
--- a/activerecord/lib/active_record/type/string.rb
+++ b/activerecord/lib/active_record/type/string.rb
@@ -11,7 +11,7 @@ module ActiveRecord
end
end
- def type_cast_for_database(value)
+ def serialize(value)
case value
when ::Numeric, ActiveSupport::Duration then value.to_s
when ::String then ::String.new(value)
diff --git a/activerecord/lib/active_record/type/value.rb b/activerecord/lib/active_record/type/value.rb
index 7338920f3b..fc3ef5e83b 100644
--- a/activerecord/lib/active_record/type/value.rb
+++ b/activerecord/lib/active_record/type/value.rb
@@ -14,12 +14,12 @@ module ActiveRecord
# Convert a value from database input to the appropriate ruby type. The
# return value of this method will be returned from
- # ActiveRecord::AttributeMethods::Read#read_attribute. See also
- # Value#type_cast and Value#cast_value.
+ # ActiveRecord::AttributeMethods::Read#read_attribute. The default
+ # implementation just calls Value#cast.
#
# +value+ The raw input, as provided from the database.
- def type_cast_from_database(value)
- type_cast(value)
+ def deserialize(value)
+ cast(value)
end
# Type casts a value from user input (e.g. from a setter). This value may
@@ -29,18 +29,18 @@ module ActiveRecord
#
# The return value of this method will be returned from
# ActiveRecord::AttributeMethods::Read#read_attribute. See also:
- # Value#type_cast and Value#cast_value.
+ # Value#cast_value.
#
# +value+ The raw input, as provided to the attribute setter.
- def type_cast_from_user(value)
- type_cast(value)
+ def cast(value)
+ cast_value(value) unless value.nil?
end
# Cast a value from the ruby type to a type that the database knows how
# to understand. The returned value from this method should be a
# +String+, +Numeric+, +Date+, +Time+, +Symbol+, +true+, +false+, or
# +nil+.
- def type_cast_for_database(value)
+ def serialize(value)
value
end
@@ -68,16 +68,16 @@ module ActiveRecord
# which could be mutated, you should override this method. You will need
# to either:
#
- # - pass +new_value+ to Value#type_cast_for_database and compare it to
+ # - pass +new_value+ to Value#serialize and compare it to
# +raw_old_value+
#
# or
#
- # - pass +raw_old_value+ to Value#type_cast_from_database and compare it to
+ # - pass +raw_old_value+ to Value#deserialize and compare it to
# +new_value+
#
# +raw_old_value+ The original value, before being passed to
- # +type_cast_from_database+.
+ # +deserialize+.
#
# +new_value+ The current value, after type casting.
def changed_in_place?(raw_old_value, new_value)
@@ -93,16 +93,8 @@ module ActiveRecord
private
- # Convenience method. If you don't need separate behavior for
- # Value#type_cast_from_database and Value#type_cast_from_user, you can override
- # this method instead. The default behavior of both methods is to call
- # this one. See also Value#cast_value.
- def type_cast(value) # :doc:
- cast_value(value) unless value.nil?
- end
-
# Convenience method for types which do not need separate type casting
- # behavior for user and database inputs. Called by Value#type_cast for
+ # behavior for user and database inputs. Called by Value#cast for
# values except +nil+.
def cast_value(value) # :doc:
value
diff --git a/activerecord/lib/active_record/type_caster/map.rb b/activerecord/lib/active_record/type_caster/map.rb
index 03c9e8ff83..4b1941351c 100644
--- a/activerecord/lib/active_record/type_caster/map.rb
+++ b/activerecord/lib/active_record/type_caster/map.rb
@@ -8,7 +8,7 @@ module ActiveRecord
def type_cast_for_database(attr_name, value)
return value if value.is_a?(Arel::Nodes::BindParam)
type = types.type_for_attribute(attr_name.to_s)
- type.type_cast_for_database(value)
+ type.serialize(value)
end
protected
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index a766d77e88..9be4b10a55 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -61,7 +61,7 @@ module ActiveRecord
column = klass.columns_hash[attribute_name]
cast_type = klass.type_for_attribute(attribute_name)
- value = cast_type.type_cast_for_database(value)
+ value = cast_type.serialize(value)
value = klass.connection.type_cast(value)
if value.is_a?(String) && column.limit
value = value.to_s[0, column.limit]
diff --git a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
index 7d0bd24ba7..48ceef365e 100644
--- a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
@@ -15,7 +15,7 @@ module ActiveRecord
assert_raise ActiveRecord::NoDatabaseError do
configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'inexistent_activerecord_unittest')
connection = ActiveRecord::Base.mysql_connection(configuration)
- connection.exec_query('drop table if exists ex')
+ connection.drop_table 'ex', if_exists: true
end
end
@@ -110,7 +110,7 @@ module ActiveRecord
result = @conn.exec_query('SELECT status FROM ex')
- assert_equal 2, result.column_types['status'].type_cast_from_database(result.last['status'])
+ assert_equal 2, result.column_types['status'].deserialize(result.last['status'])
end
end
diff --git a/activerecord/test/cases/adapters/mysql/reserved_word_test.rb b/activerecord/test/cases/adapters/mysql/reserved_word_test.rb
index 403f7cbc74..2f9c070255 100644
--- a/activerecord/test/cases/adapters/mysql/reserved_word_test.rb
+++ b/activerecord/test/cases/adapters/mysql/reserved_word_test.rb
@@ -139,7 +139,7 @@ class MysqlReservedWordTest < ActiveRecord::TestCase
# custom drop table, uses execute on connection to drop a table if it exists. note: escapes table_name
def drop_tables_directly(table_names, connection = @connection)
table_names.each do |name|
- connection.execute("DROP TABLE IF EXISTS `#{name}`")
+ connection.drop_table name, if_exists: true
end
end
diff --git a/activerecord/test/cases/adapters/mysql/schema_test.rb b/activerecord/test/cases/adapters/mysql/schema_test.rb
index ab547747df..b7f9c2ce84 100644
--- a/activerecord/test/cases/adapters/mysql/schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql/schema_test.rb
@@ -22,7 +22,7 @@ module ActiveRecord
end
teardown do
- @connection.execute "drop table if exists mysql_doubles"
+ @connection.drop_table "mysql_doubles", if_exists: true
end
class MysqlDouble < ActiveRecord::Base
diff --git a/activerecord/test/cases/adapters/mysql2/connection_test.rb b/activerecord/test/cases/adapters/mysql2/connection_test.rb
index ff8ce93248..a8b39b21d4 100644
--- a/activerecord/test/cases/adapters/mysql2/connection_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/connection_test.rb
@@ -22,7 +22,7 @@ class MysqlConnectionTest < ActiveRecord::TestCase
assert_raise ActiveRecord::NoDatabaseError do
configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'inexistent_activerecord_unittest')
connection = ActiveRecord::Base.mysql2_connection(configuration)
- connection.exec_query('drop table if exists ex')
+ connection.drop_table 'ex', if_exists: true
end
end
diff --git a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb
index 7f97b454bb..beb829fc46 100644
--- a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb
@@ -138,7 +138,7 @@ class MysqlReservedWordTest < ActiveRecord::TestCase
# custom drop table, uses execute on connection to drop a table if it exists. note: escapes table_name
def drop_tables_directly(table_names, connection = @connection)
table_names.each do |name|
- connection.execute("DROP TABLE IF EXISTS `#{name}`")
+ connection.drop_table name, if_exists: true
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index 3d5b7e5137..2163e35e70 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -28,7 +28,7 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'drop table if exists pg_arrays'
+ @connection.drop_table 'pg_arrays', if_exists: true
disable_extension!('hstore', @connection)
end
@@ -92,9 +92,9 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
end
def test_type_cast_array
- assert_equal(['1', '2', '3'], @type.type_cast_from_database('{1,2,3}'))
- assert_equal([], @type.type_cast_from_database('{}'))
- assert_equal([nil], @type.type_cast_from_database('{NULL}'))
+ assert_equal(['1', '2', '3'], @type.deserialize('{1,2,3}'))
+ assert_equal([], @type.deserialize('{}'))
+ assert_equal([nil], @type.deserialize('{NULL}'))
end
def test_type_cast_integers
@@ -206,7 +206,7 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
x = PgArray.create!(tags: tags)
x.reload
- assert_equal x.tags_before_type_cast, PgArray.type_for_attribute('tags').type_cast_for_database(tags)
+ assert_equal x.tags_before_type_cast, PgArray.type_for_attribute('tags').serialize(tags)
end
def test_quoting_non_standard_delimiters
@@ -214,8 +214,8 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
comma_delim = OID::Array.new(ActiveRecord::Type::String.new, ',')
semicolon_delim = OID::Array.new(ActiveRecord::Type::String.new, ';')
- assert_equal %({"hello,",world;}), comma_delim.type_cast_for_database(strings)
- assert_equal %({hello,;"world;"}), semicolon_delim.type_cast_for_database(strings)
+ assert_equal %({"hello,",world;}), comma_delim.serialize(strings)
+ assert_equal %({hello,;"world;"}), semicolon_delim.serialize(strings)
end
def test_mutate_array
diff --git a/activerecord/test/cases/adapters/postgresql/bit_string_test.rb b/activerecord/test/cases/adapters/postgresql/bit_string_test.rb
index 6c6b4dc22a..1a5ff4316c 100644
--- a/activerecord/test/cases/adapters/postgresql/bit_string_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/bit_string_test.rb
@@ -20,7 +20,7 @@ class PostgresqlBitStringTest < ActiveRecord::TestCase
def teardown
return unless @connection
- @connection.execute 'DROP TABLE IF EXISTS postgresql_bit_strings'
+ @connection.drop_table 'postgresql_bit_strings', if_exists: true
end
def test_bit_string_column
diff --git a/activerecord/test/cases/adapters/postgresql/bytea_test.rb b/activerecord/test/cases/adapters/postgresql/bytea_test.rb
index 678a476661..16db5ab83d 100644
--- a/activerecord/test/cases/adapters/postgresql/bytea_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/bytea_test.rb
@@ -20,7 +20,7 @@ class PostgresqlByteaTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'drop table if exists bytea_data_type'
+ @connection.drop_table 'bytea_data_type', if_exists: true
end
def test_column
@@ -40,16 +40,16 @@ class PostgresqlByteaTest < ActiveRecord::TestCase
data = "\u001F\x8B"
assert_equal('UTF-8', data.encoding.name)
- assert_equal('ASCII-8BIT', @type.type_cast_from_database(data).encoding.name)
+ assert_equal('ASCII-8BIT', @type.deserialize(data).encoding.name)
end
def test_type_cast_binary_value
data = "\u001F\x8B".force_encoding("BINARY")
- assert_equal(data, @type.type_cast_from_database(data))
+ assert_equal(data, @type.deserialize(data))
end
def test_type_case_nil
- assert_equal(nil, @type.type_cast_from_database(nil))
+ assert_equal(nil, @type.deserialize(nil))
end
def test_read_value
diff --git a/activerecord/test/cases/adapters/postgresql/cidr_test.rb b/activerecord/test/cases/adapters/postgresql/cidr_test.rb
index 54b679d3ab..6cb11d17b4 100644
--- a/activerecord/test/cases/adapters/postgresql/cidr_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/cidr_test.rb
@@ -10,14 +10,14 @@ module ActiveRecord
ip = IPAddr.new("255.0.0.0/8")
ip2 = IPAddr.new("127.0.0.1")
- assert_equal "255.0.0.0/8", type.type_cast_for_database(ip)
- assert_equal "127.0.0.1/32", type.type_cast_for_database(ip2)
+ assert_equal "255.0.0.0/8", type.serialize(ip)
+ assert_equal "127.0.0.1/32", type.serialize(ip2)
end
test "casting does nothing with non-IPAddr objects" do
type = OID::Cidr.new
- assert_equal "foo", type.type_cast_for_database("foo")
+ assert_equal "foo", type.serialize("foo")
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/citext_test.rb b/activerecord/test/cases/adapters/postgresql/citext_test.rb
index 0ee2a21484..f706847890 100644
--- a/activerecord/test/cases/adapters/postgresql/citext_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/citext_test.rb
@@ -19,7 +19,7 @@ if ActiveRecord::Base.connection.supports_extensions?
end
teardown do
- @connection.execute 'DROP TABLE IF EXISTS citexts;'
+ @connection.drop_table 'citexts', if_exists: true
disable_extension!('citext', @connection)
end
diff --git a/activerecord/test/cases/adapters/postgresql/composite_test.rb b/activerecord/test/cases/adapters/postgresql/composite_test.rb
index 83dfb18e95..16e3f90a47 100644
--- a/activerecord/test/cases/adapters/postgresql/composite_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/composite_test.rb
@@ -29,7 +29,7 @@ module PostgresqlCompositeBehavior
def teardown
super
- @connection.execute 'DROP TABLE IF EXISTS postgresql_composites'
+ @connection.drop_table 'postgresql_composites', if_exists: true
@connection.execute 'DROP TYPE IF EXISTS full_address'
reset_connection
PostgresqlComposite.reset_column_information
@@ -83,17 +83,17 @@ class PostgresqlCompositeWithCustomOIDTest < ActiveRecord::TestCase
class FullAddressType < ActiveRecord::Type::Value
def type; :full_address end
- def type_cast_from_database(value)
+ def deserialize(value)
if value =~ /\("?([^",]*)"?,"?([^",]*)"?\)/
FullAddress.new($1, $2)
end
end
- def type_cast_from_user(value)
+ def cast(value)
value
end
- def type_cast_for_database(value)
+ def serialize(value)
return if value.nil?
"(#{value.city},#{value.street})"
end
diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb
index 7bf8d12eae..55ad76c8c0 100644
--- a/activerecord/test/cases/adapters/postgresql/connection_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb
@@ -131,7 +131,7 @@ module ActiveRecord
name = @subscriber.payloads.last[:statement_name]
assert name
res = @connection.exec_query("EXPLAIN (FORMAT JSON) EXECUTE #{name}(1)")
- plan = res.column_types['QUERY PLAN'].type_cast_from_database res.rows.first.first
+ plan = res.column_types['QUERY PLAN'].deserialize res.rows.first.first
assert_operator plan.length, :>, 0
end
diff --git a/activerecord/test/cases/adapters/postgresql/domain_test.rb b/activerecord/test/cases/adapters/postgresql/domain_test.rb
index b7d776b40c..26e064c937 100644
--- a/activerecord/test/cases/adapters/postgresql/domain_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/domain_test.rb
@@ -19,7 +19,7 @@ class PostgresqlDomainTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'DROP TABLE IF EXISTS postgresql_domains'
+ @connection.drop_table 'postgresql_domains', if_exists: true
@connection.execute 'DROP DOMAIN IF EXISTS custom_money'
reset_connection
end
diff --git a/activerecord/test/cases/adapters/postgresql/enum_test.rb b/activerecord/test/cases/adapters/postgresql/enum_test.rb
index acb09b0607..7458de23d8 100644
--- a/activerecord/test/cases/adapters/postgresql/enum_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/enum_test.rb
@@ -21,7 +21,7 @@ class PostgresqlEnumTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'DROP TABLE IF EXISTS postgresql_enums'
+ @connection.drop_table 'postgresql_enums', if_exists: true
@connection.execute 'DROP TYPE IF EXISTS mood'
reset_connection
end
diff --git a/activerecord/test/cases/adapters/postgresql/full_text_test.rb b/activerecord/test/cases/adapters/postgresql/full_text_test.rb
index 81891a90fa..b83063c94e 100644
--- a/activerecord/test/cases/adapters/postgresql/full_text_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/full_text_test.rb
@@ -13,7 +13,7 @@ class PostgresqlFullTextTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'DROP TABLE IF EXISTS tsvectors;'
+ @connection.drop_table 'tsvectors', if_exists: true
end
def test_tsvector_column
diff --git a/activerecord/test/cases/adapters/postgresql/geometric_test.rb b/activerecord/test/cases/adapters/postgresql/geometric_test.rb
index 4b25381a83..41e9572907 100644
--- a/activerecord/test/cases/adapters/postgresql/geometric_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/geometric_test.rb
@@ -18,7 +18,7 @@ class PostgresqlPointTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'DROP TABLE IF EXISTS postgresql_points'
+ @connection.drop_table 'postgresql_points', if_exists: true
end
def test_column
@@ -84,7 +84,7 @@ class PostgresqlGeometricTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'DROP TABLE IF EXISTS postgresql_geometrics'
+ @connection.drop_table 'postgresql_geometrics', if_exists: true
end
def test_geometric_types
diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
index 11053a6e38..e6835031c3 100644
--- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
@@ -32,7 +32,7 @@ if ActiveRecord::Base.connection.supports_extensions?
end
teardown do
- @connection.execute 'drop table if exists hstores'
+ @connection.drop_table 'hstores', if_exists: true
end
def test_hstore_included_in_extensions
@@ -110,10 +110,10 @@ if ActiveRecord::Base.connection.supports_extensions?
end
def test_type_cast_hstore
- assert_equal({'1' => '2'}, @type.type_cast_from_database("\"1\"=>\"2\""))
- assert_equal({}, @type.type_cast_from_database(""))
- assert_equal({'key'=>nil}, @type.type_cast_from_database('key => NULL'))
- assert_equal({'c'=>'}','"a"'=>'b "a b'}, @type.type_cast_from_database(%q(c=>"}", "\"a\""=>"b \"a b")))
+ assert_equal({'1' => '2'}, @type.deserialize("\"1\"=>\"2\""))
+ assert_equal({}, @type.deserialize(""))
+ assert_equal({'key'=>nil}, @type.deserialize('key => NULL'))
+ assert_equal({'c'=>'}','"a"'=>'b "a b'}, @type.deserialize(%q(c=>"}", "\"a\""=>"b \"a b")))
end
def test_with_store_accessors
@@ -165,47 +165,47 @@ if ActiveRecord::Base.connection.supports_extensions?
end
def test_gen1
- assert_equal(%q(" "=>""), @type.type_cast_for_database({' '=>''}))
+ assert_equal(%q(" "=>""), @type.serialize({' '=>''}))
end
def test_gen2
- assert_equal(%q(","=>""), @type.type_cast_for_database({','=>''}))
+ assert_equal(%q(","=>""), @type.serialize({','=>''}))
end
def test_gen3
- assert_equal(%q("="=>""), @type.type_cast_for_database({'='=>''}))
+ assert_equal(%q("="=>""), @type.serialize({'='=>''}))
end
def test_gen4
- assert_equal(%q(">"=>""), @type.type_cast_for_database({'>'=>''}))
+ assert_equal(%q(">"=>""), @type.serialize({'>'=>''}))
end
def test_parse1
- assert_equal({'a'=>nil,'b'=>nil,'c'=>'NuLl','null'=>'c'}, @type.type_cast_from_database('a=>null,b=>NuLl,c=>"NuLl",null=>c'))
+ assert_equal({'a'=>nil,'b'=>nil,'c'=>'NuLl','null'=>'c'}, @type.deserialize('a=>null,b=>NuLl,c=>"NuLl",null=>c'))
end
def test_parse2
- assert_equal({" " => " "}, @type.type_cast_from_database("\\ =>\\ "))
+ assert_equal({" " => " "}, @type.deserialize("\\ =>\\ "))
end
def test_parse3
- assert_equal({"=" => ">"}, @type.type_cast_from_database("==>>"))
+ assert_equal({"=" => ">"}, @type.deserialize("==>>"))
end
def test_parse4
- assert_equal({"=a"=>"q=w"}, @type.type_cast_from_database('\=a=>q=w'))
+ assert_equal({"=a"=>"q=w"}, @type.deserialize('\=a=>q=w'))
end
def test_parse5
- assert_equal({"=a"=>"q=w"}, @type.type_cast_from_database('"=a"=>q\=w'))
+ assert_equal({"=a"=>"q=w"}, @type.deserialize('"=a"=>q\=w'))
end
def test_parse6
- assert_equal({"\"a"=>"q>w"}, @type.type_cast_from_database('"\"a"=>q>w'))
+ assert_equal({"\"a"=>"q>w"}, @type.deserialize('"\"a"=>q>w'))
end
def test_parse7
- assert_equal({"\"a"=>"q\"w"}, @type.type_cast_from_database('\"a=>q"w'))
+ assert_equal({"\"a"=>"q\"w"}, @type.deserialize('\"a=>q"w'))
end
def test_rewrite
diff --git a/activerecord/test/cases/adapters/postgresql/infinity_test.rb b/activerecord/test/cases/adapters/postgresql/infinity_test.rb
index 74163ac712..24199c69b8 100644
--- a/activerecord/test/cases/adapters/postgresql/infinity_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/infinity_test.rb
@@ -15,7 +15,7 @@ class PostgresqlInfinityTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute("DROP TABLE IF EXISTS postgresql_infinities")
+ @connection.drop_table 'postgresql_infinities', if_exists: true
end
test "type casting infinity on a float column" do
diff --git a/activerecord/test/cases/adapters/postgresql/integer_test.rb b/activerecord/test/cases/adapters/postgresql/integer_test.rb
index 7f8751281e..679a0fc7b3 100644
--- a/activerecord/test/cases/adapters/postgresql/integer_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/integer_test.rb
@@ -16,7 +16,7 @@ class PostgresqlIntegerTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute "drop table if exists pg_integers"
+ @connection.drop_table "pg_integers", if_exists: true
end
test "schema properly respects bigint ranges" do
diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb
index 3b123f979e..d8fded16b4 100644
--- a/activerecord/test/cases/adapters/postgresql/json_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/json_test.rb
@@ -80,13 +80,13 @@ module PostgresqlJSONSharedTestCases
type = JsonDataType.type_for_attribute("payload")
data = "{\"a_key\":\"a_value\"}"
- hash = type.type_cast_from_database(data)
+ hash = type.deserialize(data)
assert_equal({'a_key' => 'a_value'}, hash)
- assert_equal({'a_key' => 'a_value'}, type.type_cast_from_database(data))
+ assert_equal({'a_key' => 'a_value'}, type.deserialize(data))
- assert_equal({}, type.type_cast_from_database("{}"))
- assert_equal({'key'=>nil}, type.type_cast_from_database('{"key": null}'))
- assert_equal({'c'=>'}','"a"'=>'b "a b'}, type.type_cast_from_database(%q({"c":"}", "\"a\"":"b \"a b"})))
+ assert_equal({}, type.deserialize("{}"))
+ assert_equal({'key'=>nil}, type.deserialize('{"key": null}'))
+ assert_equal({'c'=>'}','"a"'=>'b "a b'}, type.deserialize(%q({"c":"}", "\"a\"":"b \"a b"})))
end
def test_rewrite
diff --git a/activerecord/test/cases/adapters/postgresql/ltree_test.rb b/activerecord/test/cases/adapters/postgresql/ltree_test.rb
index 2b3823f9f1..ce0ad16557 100644
--- a/activerecord/test/cases/adapters/postgresql/ltree_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/ltree_test.rb
@@ -22,7 +22,7 @@ class PostgresqlLtreeTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'drop table if exists ltrees'
+ @connection.drop_table 'ltrees', if_exists: true
end
def test_column
diff --git a/activerecord/test/cases/adapters/postgresql/money_test.rb b/activerecord/test/cases/adapters/postgresql/money_test.rb
index ba9af4be6f..cedd399380 100644
--- a/activerecord/test/cases/adapters/postgresql/money_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/money_test.rb
@@ -16,7 +16,7 @@ class PostgresqlMoneyTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'DROP TABLE IF EXISTS postgresql_moneys'
+ @connection.drop_table 'postgresql_moneys', if_exists: true
end
def test_column
@@ -47,10 +47,10 @@ class PostgresqlMoneyTest < ActiveRecord::TestCase
def test_money_type_cast
type = PostgresqlMoney.type_for_attribute('wealth')
- assert_equal(12345678.12, type.type_cast_from_user("$12,345,678.12"))
- assert_equal(12345678.12, type.type_cast_from_user("$12.345.678,12"))
- assert_equal(-1.15, type.type_cast_from_user("-$1.15"))
- assert_equal(-2.25, type.type_cast_from_user("($2.25)"))
+ assert_equal(12345678.12, type.cast("$12,345,678.12"))
+ assert_equal(12345678.12, type.cast("$12.345.678,12"))
+ assert_equal(-1.15, type.cast("-$1.15"))
+ assert_equal(-2.25, type.cast("($2.25)"))
end
def test_schema_dumping
diff --git a/activerecord/test/cases/adapters/postgresql/network_test.rb b/activerecord/test/cases/adapters/postgresql/network_test.rb
index 4cd2d4d5f3..033695518e 100644
--- a/activerecord/test/cases/adapters/postgresql/network_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/network_test.rb
@@ -15,7 +15,7 @@ class PostgresqlNetworkTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'DROP TABLE IF EXISTS postgresql_network_addresses'
+ @connection.drop_table 'postgresql_network_addresses', if_exists: true
end
def test_cidr_column
diff --git a/activerecord/test/cases/adapters/postgresql/numbers_test.rb b/activerecord/test/cases/adapters/postgresql/numbers_test.rb
index 70aa898439..093b81fe8d 100644
--- a/activerecord/test/cases/adapters/postgresql/numbers_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/numbers_test.rb
@@ -12,7 +12,7 @@ class PostgresqlNumberTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'DROP TABLE IF EXISTS postgresql_numbers'
+ @connection.drop_table 'postgresql_numbers', if_exists: true
end
def test_data_type
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index 564712522d..a934180a43 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -227,8 +227,8 @@ module ActiveRecord
"DELETE FROM pg_depend WHERE objid = 'ex2_id_seq'::regclass AND refobjid = 'ex'::regclass AND deptype = 'a'"
)
ensure
- @connection.exec_query('DROP TABLE IF EXISTS ex')
- @connection.exec_query('DROP TABLE IF EXISTS ex2')
+ @connection.drop_table 'ex', if_exists: true
+ @connection.drop_table 'ex2', if_exists: true
end
def test_exec_insert_number
diff --git a/activerecord/test/cases/adapters/postgresql/quoting_test.rb b/activerecord/test/cases/adapters/postgresql/quoting_test.rb
index 60baacf67a..e4420d9d13 100644
--- a/activerecord/test/cases/adapters/postgresql/quoting_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/quoting_test.rb
@@ -30,13 +30,13 @@ module ActiveRecord
def test_quote_range
range = "1,2]'; SELECT * FROM users; --".."a"
type = OID::Range.new(Type::Integer.new, :int8range)
- assert_equal "'[1,0]'", @conn.quote(type.type_cast_for_database(range))
+ assert_equal "'[1,0]'", @conn.quote(type.serialize(range))
end
def test_quote_bit_string
value = "'); SELECT * FROM users; /*\n01\n*/--"
type = OID::Bit.new
- assert_equal nil, @conn.quote(type.type_cast_for_database(value))
+ assert_equal nil, @conn.quote(type.serialize(value))
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/range_test.rb b/activerecord/test/cases/adapters/postgresql/range_test.rb
index 70cf21100a..b6b451ca5c 100644
--- a/activerecord/test/cases/adapters/postgresql/range_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/range_test.rb
@@ -91,7 +91,7 @@ _SQL
end
teardown do
- @connection.execute 'DROP TABLE IF EXISTS postgresql_ranges'
+ @connection.drop_table 'postgresql_ranges', if_exists: true
@connection.execute 'DROP TYPE IF EXISTS floatrange'
reset_connection
end
diff --git a/activerecord/test/cases/adapters/postgresql/rename_table_test.rb b/activerecord/test/cases/adapters/postgresql/rename_table_test.rb
index 056a035622..f507328868 100644
--- a/activerecord/test/cases/adapters/postgresql/rename_table_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/rename_table_test.rb
@@ -7,8 +7,8 @@ class PostgresqlRenameTableTest < ActiveRecord::TestCase
end
def teardown
- @connection.execute 'DROP TABLE IF EXISTS "before_rename"'
- @connection.execute 'DROP TABLE IF EXISTS "after_rename"'
+ @connection.drop_table "before_rename", if_exists: true
+ @connection.drop_table "after_rename", if_exists: true
end
test "renaming a table also renames the primary key index" do
diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb
index 83e35ad1a1..77ff6d01bc 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb
@@ -460,8 +460,8 @@ class SchemaForeignKeyTest < ActiveRecord::TestCase
output = dump_table_schema "wagons"
assert_match %r{\s+add_foreign_key "wagons", "my_schema\.trains", column: "train_id"$}, output
ensure
- @connection.execute "DROP TABLE IF EXISTS wagons"
- @connection.execute "DROP TABLE IF EXISTS my_schema.trains"
+ @connection.drop_table "wagons", if_exists: true
+ @connection.drop_table "my_schema.trains", if_exists: true
@connection.execute "DROP SCHEMA IF EXISTS my_schema"
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb b/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
index 4506e874bc..c0907b8f21 100644
--- a/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
@@ -18,8 +18,8 @@ class PostgresqlTypeLookupTest < ActiveRecord::TestCase
bigint_array = @connection.type_map.lookup(1016, -1, "bigint[]")
big_array = [123456789123456789]
- assert_raises(RangeError) { int_array.type_cast_for_database(big_array) }
- assert_equal "{123456789123456789}", bigint_array.type_cast_for_database(big_array)
+ assert_raises(RangeError) { int_array.serialize(big_array) }
+ assert_equal "{123456789123456789}", bigint_array.serialize(big_array)
end
test "range types correctly respect registration of subtypes" do
@@ -27,7 +27,7 @@ class PostgresqlTypeLookupTest < ActiveRecord::TestCase
bigint_range = @connection.type_map.lookup(3926, -1, "int8range")
big_range = 0..123456789123456789
- assert_raises(RangeError) { int_range.type_cast_for_database(big_range) }
- assert_equal "[0,123456789123456789]", bigint_range.type_cast_for_database(big_range)
+ assert_raises(RangeError) { int_range.serialize(big_range) }
+ assert_equal "[0,123456789123456789]", bigint_range.serialize(big_range)
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb
index 6693843497..1219e197ab 100644
--- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb
@@ -7,7 +7,7 @@ module PostgresqlUUIDHelper
end
def drop_table(name)
- connection.execute "drop table if exists #{name}"
+ connection.drop_table name, if_exists: true
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/xml_test.rb b/activerecord/test/cases/adapters/postgresql/xml_test.rb
index 05b34dcf7d..b097deb2f4 100644
--- a/activerecord/test/cases/adapters/postgresql/xml_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/xml_test.rb
@@ -22,7 +22,7 @@ class PostgresqlXMLTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute 'drop table if exists xml_data_type'
+ @connection.drop_table 'xml_data_type', if_exists: true
end
def test_column
diff --git a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
index c1d9b7c273..243f65df98 100644
--- a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
@@ -87,7 +87,7 @@ module ActiveRecord
value = "hello".encode('ascii-8bit')
type = Type::String.new
- assert_equal "'hello'", @conn.quote(type.type_cast_for_database(value))
+ assert_equal "'hello'", @conn.quote(type.serialize(value))
end
end
end
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
index f916d99bcf..5ca3c92027 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -22,7 +22,7 @@ module ActiveRecord
def test_bad_connection
assert_raise ActiveRecord::NoDatabaseError do
connection = ActiveRecord::Base.sqlite3_connection(adapter: "sqlite3", database: "/tmp/should/_not/_exist/-cinco-dog.db")
- connection.exec_query('drop table if exists ex')
+ connection.drop_table 'ex', if_exists: true
end
end
@@ -191,7 +191,7 @@ module ActiveRecord
binary.save!
assert_equal str, binary.data
ensure
- DualEncoding.connection.execute('DROP TABLE IF EXISTS dual_encodings')
+ DualEncoding.connection.drop_table 'dual_encodings', if_exists: true
end
def test_type_cast_should_not_mutate_encoding
diff --git a/activerecord/test/cases/attribute_decorators_test.rb b/activerecord/test/cases/attribute_decorators_test.rb
index 0b96319cbd..2aeb2601c2 100644
--- a/activerecord/test/cases/attribute_decorators_test.rb
+++ b/activerecord/test/cases/attribute_decorators_test.rb
@@ -12,11 +12,11 @@ module ActiveRecord
super(delegate)
end
- def type_cast_from_user(value)
+ def cast(value)
"#{super} #{@decoration}"
end
- alias type_cast_from_database type_cast_from_user
+ alias deserialize cast
end
setup do
@@ -102,11 +102,11 @@ module ActiveRecord
end
class Multiplier < SimpleDelegator
- def type_cast_from_user(value)
+ def cast(value)
return if value.nil?
value * 2
end
- alias type_cast_from_database type_cast_from_user
+ alias deserialize cast
end
test "decorating with a proc" do
diff --git a/activerecord/test/cases/attribute_set_test.rb b/activerecord/test/cases/attribute_set_test.rb
index 112cd2fb14..9d927481ec 100644
--- a/activerecord/test/cases/attribute_set_test.rb
+++ b/activerecord/test/cases/attribute_set_test.rb
@@ -151,12 +151,12 @@ module ActiveRecord
end
class MyType
- def type_cast_from_user(value)
+ def cast(value)
return if value.nil?
value + " from user"
end
- def type_cast_from_database(value)
+ def deserialize(value)
return if value.nil?
value + " from database"
end
diff --git a/activerecord/test/cases/attribute_test.rb b/activerecord/test/cases/attribute_test.rb
index eac73e11e8..aa419c7a67 100644
--- a/activerecord/test/cases/attribute_test.rb
+++ b/activerecord/test/cases/attribute_test.rb
@@ -13,7 +13,7 @@ module ActiveRecord
end
test "from_database + read type casts from database" do
- @type.expect(:type_cast_from_database, 'type cast from database', ['a value'])
+ @type.expect(:deserialize, 'type cast from database', ['a value'])
attribute = Attribute.from_database(nil, 'a value', @type)
type_cast_value = attribute.value
@@ -22,7 +22,7 @@ module ActiveRecord
end
test "from_user + read type casts from user" do
- @type.expect(:type_cast_from_user, 'type cast from user', ['a value'])
+ @type.expect(:cast, 'type cast from user', ['a value'])
attribute = Attribute.from_user(nil, 'a value', @type)
type_cast_value = attribute.value
@@ -31,7 +31,7 @@ module ActiveRecord
end
test "reading memoizes the value" do
- @type.expect(:type_cast_from_database, 'from the database', ['whatever'])
+ @type.expect(:deserialize, 'from the database', ['whatever'])
attribute = Attribute.from_database(nil, 'whatever', @type)
type_cast_value = attribute.value
@@ -42,7 +42,7 @@ module ActiveRecord
end
test "reading memoizes falsy values" do
- @type.expect(:type_cast_from_database, false, ['whatever'])
+ @type.expect(:deserialize, false, ['whatever'])
attribute = Attribute.from_database(nil, 'whatever', @type)
attribute.value
@@ -58,27 +58,27 @@ module ActiveRecord
end
test "from_database + read_for_database type casts to and from database" do
- @type.expect(:type_cast_from_database, 'read from database', ['whatever'])
- @type.expect(:type_cast_for_database, 'ready for database', ['read from database'])
+ @type.expect(:deserialize, 'read from database', ['whatever'])
+ @type.expect(:serialize, 'ready for database', ['read from database'])
attribute = Attribute.from_database(nil, 'whatever', @type)
- type_cast_for_database = attribute.value_for_database
+ serialize = attribute.value_for_database
- assert_equal 'ready for database', type_cast_for_database
+ assert_equal 'ready for database', serialize
end
test "from_user + read_for_database type casts from the user to the database" do
- @type.expect(:type_cast_from_user, 'read from user', ['whatever'])
- @type.expect(:type_cast_for_database, 'ready for database', ['read from user'])
+ @type.expect(:cast, 'read from user', ['whatever'])
+ @type.expect(:serialize, 'ready for database', ['read from user'])
attribute = Attribute.from_user(nil, 'whatever', @type)
- type_cast_for_database = attribute.value_for_database
+ serialize = attribute.value_for_database
- assert_equal 'ready for database', type_cast_for_database
+ assert_equal 'ready for database', serialize
end
test "duping dups the value" do
- @type.expect(:type_cast_from_database, 'type cast', ['a value'])
+ @type.expect(:deserialize, 'type cast', ['a value'])
attribute = Attribute.from_database(nil, 'a value', @type)
value_from_orig = attribute.value
@@ -90,7 +90,7 @@ module ActiveRecord
end
test "duping does not dup the value if it is not dupable" do
- @type.expect(:type_cast_from_database, false, ['a value'])
+ @type.expect(:deserialize, false, ['a value'])
attribute = Attribute.from_database(nil, 'a value', @type)
assert_same attribute.value, attribute.dup.value
@@ -102,11 +102,11 @@ module ActiveRecord
end
class MyType
- def type_cast_from_user(value)
+ def cast(value)
value + " from user"
end
- def type_cast_from_database(value)
+ def deserialize(value)
value + " from database"
end
end
diff --git a/activerecord/test/cases/attributes_test.rb b/activerecord/test/cases/attributes_test.rb
index a753e8b74e..e7b76b1cf9 100644
--- a/activerecord/test/cases/attributes_test.rb
+++ b/activerecord/test/cases/attributes_test.rb
@@ -108,11 +108,11 @@ module ActiveRecord
test "the given default value is cast from user" do
custom_type = Class.new(Type::Value) do
- def type_cast_from_user(*)
+ def cast(*)
"from user"
end
- def type_cast_from_database(*)
+ def deserialize(*)
"from database"
end
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index ef1173a2ba..76907c832f 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1427,7 +1427,7 @@ class BasicsTest < ActiveRecord::TestCase
attrs.delete 'id'
typecast = Class.new(ActiveRecord::Type::Value) {
- def type_cast value
+ def cast value
"t.lo"
end
}
diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb
index c05382598b..9e428098e4 100644
--- a/activerecord/test/cases/batches_test.rb
+++ b/activerecord/test/cases/batches_test.rb
@@ -37,9 +37,9 @@ class EachTest < ActiveRecord::TestCase
if Enumerator.method_defined? :size
def test_each_should_return_a_sized_enumerator
- assert_equal 11, Post.find_each(:batch_size => 1).size
- assert_equal 5, Post.find_each(:batch_size => 2, :start => 7).size
- assert_equal 11, Post.find_each(:batch_size => 10_000).size
+ assert_equal 11, Post.find_each(batch_size: 1).size
+ assert_equal 5, Post.find_each(batch_size: 2, begin_at: 7).size
+ assert_equal 11, Post.find_each(batch_size: 10_000).size
end
end
@@ -99,7 +99,7 @@ class EachTest < ActiveRecord::TestCase
def test_find_in_batches_should_start_from_the_start_option
assert_queries(@total) do
- Post.find_in_batches(:batch_size => 1, :start => 2) do |batch|
+ Post.find_in_batches(batch_size: 1, begin_at: 2) do |batch|
assert_kind_of Array, batch
assert_kind_of Post, batch.first
end
@@ -172,7 +172,7 @@ class EachTest < ActiveRecord::TestCase
def test_find_in_batches_should_not_modify_passed_options
assert_nothing_raised do
- Post.find_in_batches({ batch_size: 42, start: 1 }.freeze){}
+ Post.find_in_batches({ batch_size: 42, begin_at: 1 }.freeze){}
end
end
@@ -181,7 +181,7 @@ class EachTest < ActiveRecord::TestCase
start_nick = nick_order_subscribers.second.nick
subscribers = []
- Subscriber.find_in_batches(:batch_size => 1, :start => start_nick) do |batch|
+ Subscriber.find_in_batches(batch_size: 1, begin_at: start_nick) do |batch|
subscribers.concat(batch)
end
@@ -209,11 +209,32 @@ class EachTest < ActiveRecord::TestCase
end
end
+ def test_find_in_batches_start_deprecated
+ assert_deprecated do
+ assert_queries(@total) do
+ Post.find_in_batches(batch_size: 1, start: 2) do |batch|
+ assert_kind_of Array, batch
+ assert_kind_of Post, batch.first
+ end
+ end
+ end
+ end
+
+ def test_find_each_start_deprecated
+ assert_deprecated do
+ assert_queries(@total) do
+ Post.find_each(batch_size: 1, start: 2) do |post|
+ assert_kind_of Post, post
+ end
+ end
+ end
+ end
+
if Enumerator.method_defined? :size
def test_find_in_batches_should_return_a_sized_enumerator
assert_equal 11, Post.find_in_batches(:batch_size => 1).size
assert_equal 6, Post.find_in_batches(:batch_size => 2).size
- assert_equal 4, Post.find_in_batches(:batch_size => 2, :start => 4).size
+ assert_equal 4, Post.find_in_batches(batch_size: 2, begin_at: 4).size
assert_equal 4, Post.find_in_batches(:batch_size => 3).size
assert_equal 1, Post.find_in_batches(:batch_size => 10_000).size
end
diff --git a/activerecord/test/cases/connection_adapters/type_lookup_test.rb b/activerecord/test/cases/connection_adapters/type_lookup_test.rb
index ac2e0053b8..05c57985a1 100644
--- a/activerecord/test/cases/connection_adapters/type_lookup_test.rb
+++ b/activerecord/test/cases/connection_adapters/type_lookup_test.rb
@@ -90,7 +90,7 @@ module ActiveRecord
cast_type = @connection.type_map.lookup(type)
assert_equal :decimal, cast_type.type
- assert_equal 2, cast_type.type_cast_from_user(2.1)
+ assert_equal 2, cast_type.cast(2.1)
end
end
diff --git a/activerecord/test/cases/date_time_precision_test.rb b/activerecord/test/cases/date_time_precision_test.rb
index 720f10a9d3..4602ba6d0d 100644
--- a/activerecord/test/cases/date_time_precision_test.rb
+++ b/activerecord/test/cases/date_time_precision_test.rb
@@ -1,7 +1,7 @@
require 'cases/helper'
require 'support/schema_dumping_helper'
-if ActiveRecord::Base.connection.supports_datetime_with_precision?
+if mysql_56? || current_adapter?(:PostgreSQLAdapter)
class DateTimePrecisionTest < ActiveRecord::TestCase
include SchemaDumpingHelper
self.use_transactional_fixtures = false
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index c2573ac72b..3a7cc572e6 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -623,13 +623,13 @@ class DirtyTest < ActiveRecord::TestCase
end
end
- test "defaults with type that implements `type_cast_for_database`" do
+ test "defaults with type that implements `serialize`" do
type = Class.new(ActiveRecord::Type::Value) do
- def type_cast(value)
+ def cast(value)
value.to_i
end
- def type_cast_for_database(value)
+ def serialize(value)
value.to_s
end
end
diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb
index ed568413a2..e70d492efd 100644
--- a/activerecord/test/cases/enum_test.rb
+++ b/activerecord/test/cases/enum_test.rb
@@ -26,15 +26,47 @@ class EnumTest < ActiveRecord::TestCase
assert_equal @book, Book.unread.first
end
- test "build from scope" do
- assert Book.proposed.build.proposed?
- refute Book.proposed.build.written?
- assert Book.where(status: Book.statuses[:proposed]).build.proposed?
+ test "find via where with values" do
+ proposed, written = Book.statuses[:proposed], Book.statuses[:written]
+
+ assert_equal @book, Book.where(status: proposed).first
+ refute_equal @book, Book.where(status: written).first
+ assert_equal @book, Book.where(status: [proposed]).first
+ refute_equal @book, Book.where(status: [written]).first
+ refute_equal @book, Book.where("status <> ?", proposed).first
+ assert_equal @book, Book.where("status <> ?", written).first
+ end
+
+ test "find via where with symbols" do
+ assert_equal @book, Book.where(status: :proposed).first
+ refute_equal @book, Book.where(status: :written).first
+ assert_equal @book, Book.where(status: [:proposed]).first
+ refute_equal @book, Book.where(status: [:written]).first
+ refute_equal @book, Book.where.not(status: :proposed).first
+ assert_equal @book, Book.where.not(status: :written).first
end
- test "find via where" do
+ test "find via where with strings" do
assert_equal @book, Book.where(status: "proposed").first
refute_equal @book, Book.where(status: "written").first
+ assert_equal @book, Book.where(status: ["proposed"]).first
+ refute_equal @book, Book.where(status: ["written"]).first
+ refute_equal @book, Book.where.not(status: "proposed").first
+ assert_equal @book, Book.where.not(status: "written").first
+ end
+
+ test "build from scope" do
+ assert Book.written.build.written?
+ refute Book.written.build.proposed?
+ end
+
+ test "build from where" do
+ assert Book.where(status: Book.statuses[:written]).build.written?
+ refute Book.where(status: Book.statuses[:written]).build.proposed?
+ assert Book.where(status: :written).build.written?
+ refute Book.where(status: :written).build.proposed?
+ assert Book.where(status: "written").build.written?
+ refute Book.where(status: "written").build.proposed?
end
test "update by declaration" do
@@ -140,19 +172,24 @@ class EnumTest < ActiveRecord::TestCase
assert_equal "'unknown' is not a valid status", e.message
end
+ test "NULL values from database should be casted to nil" do
+ Book.where(id: @book.id).update_all("status = NULL")
+ assert_nil @book.reload.status
+ end
+
test "assign nil value" do
@book.status = nil
- assert @book.status.nil?
+ assert_nil @book.status
end
test "assign empty string value" do
@book.status = ''
- assert @book.status.nil?
+ assert_nil @book.status
end
test "assign long empty string value" do
@book.status = ' '
- assert @book.status.nil?
+ assert_nil @book.status
end
test "constant to access the mapping" do
diff --git a/activerecord/test/cases/migration/change_schema_test.rb b/activerecord/test/cases/migration/change_schema_test.rb
index 3cd4073a38..30c91dfdcb 100644
--- a/activerecord/test/cases/migration/change_schema_test.rb
+++ b/activerecord/test/cases/migration/change_schema_test.rb
@@ -68,8 +68,8 @@ module ActiveRecord
five = columns.detect { |c| c.name == "five" } unless mysql
assert_equal "hello", one.default
- assert_equal true, connection.lookup_cast_type_from_column(two).type_cast_from_database(two.default)
- assert_equal false, connection.lookup_cast_type_from_column(three).type_cast_from_database(three.default)
+ assert_equal true, connection.lookup_cast_type_from_column(two).deserialize(two.default)
+ assert_equal false, connection.lookup_cast_type_from_column(three).deserialize(three.default)
assert_equal '1', four.default
assert_equal "hello", five.default unless mysql
end
diff --git a/activerecord/test/cases/migration/columns_test.rb b/activerecord/test/cases/migration/columns_test.rb
index 6f65288ac0..e5ccfe0f91 100644
--- a/activerecord/test/cases/migration/columns_test.rb
+++ b/activerecord/test/cases/migration/columns_test.rb
@@ -196,7 +196,7 @@ module ActiveRecord
old_columns = connection.columns(TestModel.table_name)
assert old_columns.find { |c|
- default = connection.lookup_cast_type_from_column(c).type_cast_from_database(c.default)
+ default = connection.lookup_cast_type_from_column(c).deserialize(c.default)
c.name == 'approved' && c.type == :boolean && default == true
}
@@ -204,11 +204,11 @@ module ActiveRecord
new_columns = connection.columns(TestModel.table_name)
assert_not new_columns.find { |c|
- default = connection.lookup_cast_type_from_column(c).type_cast_from_database(c.default)
+ default = connection.lookup_cast_type_from_column(c).deserialize(c.default)
c.name == 'approved' and c.type == :boolean and default == true
}
assert new_columns.find { |c|
- default = connection.lookup_cast_type_from_column(c).type_cast_from_database(c.default)
+ default = connection.lookup_cast_type_from_column(c).deserialize(c.default)
c.name == 'approved' and c.type == :boolean and default == false
}
change_column :test_models, :approved, :boolean, :default => true
diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb
index b2f2d077eb..7f4790bf3e 100644
--- a/activerecord/test/cases/migration/foreign_key_test.rb
+++ b/activerecord/test/cases/migration/foreign_key_test.rb
@@ -147,6 +147,27 @@ module ActiveRecord
assert_equal :nullify, fk.on_update
end
+ def test_foreign_key_exists
+ @connection.add_foreign_key :astronauts, :rockets
+
+ assert @connection.foreign_key_exists?(:astronauts, :rockets)
+ assert_not @connection.foreign_key_exists?(:astronauts, :stars)
+ end
+
+ def test_foreign_key_exists_by_column
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
+
+ assert @connection.foreign_key_exists?(:astronauts, column: "rocket_id")
+ assert_not @connection.foreign_key_exists?(:astronauts, column: "star_id")
+ end
+
+ def test_foreign_key_exists_by_name
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk"
+
+ assert @connection.foreign_key_exists?(:astronauts, name: "fancy_named_fk")
+ assert_not @connection.foreign_key_exists?(:astronauts, name: "other_fancy_named_fk")
+ end
+
def test_remove_foreign_key_inferes_column
@connection.add_foreign_key :astronauts, :rockets
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index 4b668f84dd..b45fbf0143 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -260,7 +260,7 @@ if current_adapter?(:PostgreSQLAdapter, :MysqlAdapter, :Mysql2Adapter)
end
teardown do
- @connection.execute("DROP TABLE IF EXISTS widgets")
+ @connection.drop_table 'widgets', if_exists: true
end
test "primary key column type with bigserial" do
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index b0e40c7145..67e9bef808 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -92,9 +92,9 @@ class ReflectionTest < ActiveRecord::TestCase
type = @first.type_for_attribute("attribute_that_doesnt_exist")
object = Object.new
- assert_equal object, type.type_cast_from_database(object)
- assert_equal object, type.type_cast_from_user(object)
- assert_equal object, type.type_cast_for_database(object)
+ assert_equal object, type.deserialize(object)
+ assert_equal object, type.cast(object)
+ assert_equal object, type.serialize(object)
end
def test_reflection_klass_for_nested_class_name
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb
index c9c05b75a6..9353be1ba7 100644
--- a/activerecord/test/cases/relation_test.rb
+++ b/activerecord/test/cases/relation_test.rb
@@ -254,12 +254,12 @@ module ActiveRecord
:string
end
- def type_cast_from_database(value)
+ def deserialize(value)
raise value unless value == "type cast for database"
"type cast from database"
end
- def type_cast_for_database(value)
+ def serialize(value)
raise value unless value == "value from user"
"type cast for database"
end
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index bafc9fa81b..0413984729 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -362,7 +362,7 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
teardown do
return unless @connection
- @connection.execute 'DROP TABLE defaults' if @connection.table_exists? 'defaults'
+ @connection.drop_table 'defaults', if_exists: true
end
def test_schema_dump_defaults_with_universally_supported_types
diff --git a/activerecord/test/cases/secure_token_test.rb b/activerecord/test/cases/secure_token_test.rb
index 3f7455d12d..e731443fc2 100644
--- a/activerecord/test/cases/secure_token_test.rb
+++ b/activerecord/test/cases/secure_token_test.rb
@@ -22,4 +22,11 @@ class SecureTokenTest < ActiveRecord::TestCase
assert_not_equal @user.token, old_token
assert_not_equal @user.auth_token, old_auth_token
end
+
+ def test_token_value_not_overwritten_when_present
+ @user.token = "custom-secure-token"
+ @user.save
+
+ assert_equal @user.token, "custom-secure-token"
+ end
end
diff --git a/activerecord/test/cases/time_precision_test.rb b/activerecord/test/cases/time_precision_test.rb
deleted file mode 100644
index 23422fd50a..0000000000
--- a/activerecord/test/cases/time_precision_test.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-require 'cases/helper'
-
-if ActiveRecord::Base.connection.supports_datetime_with_precision?
-class TimePrecisionTest < ActiveRecord::TestCase
- setup do
- @connection = ActiveRecord::Base.connection
- end
-
- teardown do
- @connection.drop_table :foos, if_exists: true
- end
-
- def test_time_data_type_with_precision
- @connection.create_table(:foos, force: true)
- @connection.add_column :foos, :start, :time, precision: 3
- @connection.add_column :foos, :finish, :time, precision: 6
- assert_equal 3, activerecord_column_option('foos', 'start', 'precision')
- assert_equal 6, activerecord_column_option('foos', 'finish', 'precision')
- end
-
- def test_passing_precision_to_time_does_not_set_limit
- @connection.create_table(:foos, force: true) do |t|
- t.time :start, precision: 3
- t.time :finish, precision: 6
- end
- assert_nil activerecord_column_option('foos', 'start', 'limit')
- assert_nil activerecord_column_option('foos', 'finish', 'limit')
- end
-
- def test_invalid_time_precision_raises_error
- assert_raises ActiveRecord::ActiveRecordError do
- @connection.create_table(:foos, force: true) do |t|
- t.time :start, precision: 7
- t.time :finish, precision: 7
- end
- end
- end
-
- def test_database_agrees_with_activerecord_about_precision
- @connection.create_table(:foos, force: true) do |t|
- t.time :start, precision: 2
- t.time :finish, precision: 4
- end
- assert_equal 2, database_datetime_precision('foos', 'start')
- assert_equal 4, database_datetime_precision('foos', 'finish')
- end
-
- private
-
- def database_datetime_precision(table_name, column_name)
- results = @connection.exec_query("SELECT column_name, datetime_precision FROM information_schema.columns WHERE table_name = '#{table_name}'")
- result = results.find do |result_hash|
- result_hash["column_name"] == column_name
- end
- result && result["datetime_precision"].to_i
- end
-
- def activerecord_column_option(tablename, column_name, option)
- result = @connection.columns(tablename).find do |column|
- column.name == column_name
- end
- result && result.send(option)
- end
-end
-end
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index d1d8e71c34..88e595c39f 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -668,7 +668,7 @@ class TransactionTest < ActiveRecord::TestCase
end
end
ensure
- connection.execute("DROP TABLE IF EXISTS transaction_without_primary_keys")
+ connection.drop_table 'transaction_without_primary_keys', if_exists: true
end
private
diff --git a/activerecord/test/cases/type/adapter_specific_registry_test.rb b/activerecord/test/cases/type/adapter_specific_registry_test.rb
new file mode 100644
index 0000000000..8b836b4793
--- /dev/null
+++ b/activerecord/test/cases/type/adapter_specific_registry_test.rb
@@ -0,0 +1,133 @@
+require "cases/helper"
+
+module ActiveRecord
+ class AdapterSpecificRegistryTest < ActiveRecord::TestCase
+ test "a class can be registered for a symbol" do
+ registry = Type::AdapterSpecificRegistry.new
+ registry.register(:foo, ::String)
+ registry.register(:bar, ::Array)
+
+ assert_equal "", registry.lookup(:foo)
+ assert_equal [], registry.lookup(:bar)
+ end
+
+ test "a block can be registered" do
+ registry = Type::AdapterSpecificRegistry.new
+ registry.register(:foo) do |*args|
+ [*args, "block for foo"]
+ end
+ registry.register(:bar) do |*args|
+ [*args, "block for bar"]
+ end
+
+ assert_equal [:foo, 1, "block for foo"], registry.lookup(:foo, 1)
+ assert_equal [:foo, 2, "block for foo"], registry.lookup(:foo, 2)
+ assert_equal [:bar, 1, 2, 3, "block for bar"], registry.lookup(:bar, 1, 2, 3)
+ end
+
+ test "filtering by adapter" do
+ registry = Type::AdapterSpecificRegistry.new
+ registry.register(:foo, String, adapter: :sqlite3)
+ registry.register(:foo, Array, adapter: :postgresql)
+
+ assert_equal "", registry.lookup(:foo, adapter: :sqlite3)
+ assert_equal [], registry.lookup(:foo, adapter: :postgresql)
+ end
+
+ test "an error is raised if both a generic and adapter specific type match" do
+ registry = Type::AdapterSpecificRegistry.new
+ registry.register(:foo, String)
+ registry.register(:foo, Array, adapter: :postgresql)
+
+ assert_raises TypeConflictError do
+ registry.lookup(:foo, adapter: :postgresql)
+ end
+ assert_equal "", registry.lookup(:foo, adapter: :sqlite3)
+ end
+
+ test "a generic type can explicitly override an adapter specific type" do
+ registry = Type::AdapterSpecificRegistry.new
+ registry.register(:foo, String, override: true)
+ registry.register(:foo, Array, adapter: :postgresql)
+
+ assert_equal "", registry.lookup(:foo, adapter: :postgresql)
+ assert_equal "", registry.lookup(:foo, adapter: :sqlite3)
+ end
+
+ test "a generic type can explicitly allow an adapter type to be used instead" do
+ registry = Type::AdapterSpecificRegistry.new
+ registry.register(:foo, String, override: false)
+ registry.register(:foo, Array, adapter: :postgresql)
+
+ assert_equal [], registry.lookup(:foo, adapter: :postgresql)
+ assert_equal "", registry.lookup(:foo, adapter: :sqlite3)
+ end
+
+ test "a reasonable error is given when no type is found" do
+ registry = Type::AdapterSpecificRegistry.new
+
+ e = assert_raises(ArgumentError) do
+ registry.lookup(:foo)
+ end
+
+ assert_equal "Unknown type :foo", e.message
+ end
+
+ test "construct args are passed to the type" do
+ type = Struct.new(:args)
+ registry = Type::AdapterSpecificRegistry.new
+ registry.register(:foo, type)
+
+ assert_equal type.new, registry.lookup(:foo)
+ assert_equal type.new(:ordered_arg), registry.lookup(:foo, :ordered_arg)
+ assert_equal type.new(keyword: :arg), registry.lookup(:foo, keyword: :arg)
+ assert_equal type.new(keyword: :arg), registry.lookup(:foo, keyword: :arg, adapter: :postgresql)
+ end
+
+ test "registering a modifier" do
+ decoration = Struct.new(:value)
+ registry = Type::AdapterSpecificRegistry.new
+ registry.register(:foo, String)
+ registry.register(:bar, Hash)
+ registry.add_modifier({ array: true }, decoration)
+
+ assert_equal decoration.new(""), registry.lookup(:foo, array: true)
+ assert_equal decoration.new({}), registry.lookup(:bar, array: true)
+ assert_equal "", registry.lookup(:foo)
+ end
+
+ test "registering multiple modifiers" do
+ decoration = Struct.new(:value)
+ other_decoration = Struct.new(:value)
+ registry = Type::AdapterSpecificRegistry.new
+ registry.register(:foo, String)
+ registry.add_modifier({ array: true }, decoration)
+ registry.add_modifier({ range: true }, other_decoration)
+
+ assert_equal "", registry.lookup(:foo)
+ assert_equal decoration.new(""), registry.lookup(:foo, array: true)
+ assert_equal other_decoration.new(""), registry.lookup(:foo, range: true)
+ assert_equal(
+ decoration.new(other_decoration.new("")),
+ registry.lookup(:foo, array: true, range: true)
+ )
+ end
+
+ test "registering adapter specific modifiers" do
+ decoration = Struct.new(:value)
+ type = Struct.new(:args)
+ registry = Type::AdapterSpecificRegistry.new
+ registry.register(:foo, type)
+ registry.add_modifier({ array: true }, decoration, adapter: :postgresql)
+
+ assert_equal(
+ decoration.new(type.new(keyword: :arg)),
+ registry.lookup(:foo, array: true, adapter: :postgresql, keyword: :arg)
+ )
+ assert_equal(
+ type.new(array: true),
+ registry.lookup(:foo, array: true, adapter: :sqlite3)
+ )
+ end
+ end
+end
diff --git a/activerecord/test/cases/type/decimal_test.rb b/activerecord/test/cases/type/decimal_test.rb
index 34ed1d7b19..fe49d0e79a 100644
--- a/activerecord/test/cases/type/decimal_test.rb
+++ b/activerecord/test/cases/type/decimal_test.rb
@@ -5,29 +5,29 @@ module ActiveRecord
class DecimalTest < ActiveRecord::TestCase
def test_type_cast_decimal
type = Decimal.new
- assert_equal BigDecimal.new("0"), type.type_cast_from_user(BigDecimal.new("0"))
- assert_equal BigDecimal.new("123"), type.type_cast_from_user(123.0)
- assert_equal BigDecimal.new("1"), type.type_cast_from_user(:"1")
+ assert_equal BigDecimal.new("0"), type.cast(BigDecimal.new("0"))
+ assert_equal BigDecimal.new("123"), type.cast(123.0)
+ assert_equal BigDecimal.new("1"), type.cast(:"1")
end
def test_type_cast_decimal_from_float_with_large_precision
type = Decimal.new(precision: ::Float::DIG + 2)
- assert_equal BigDecimal.new("123.0"), type.type_cast_from_user(123.0)
+ assert_equal BigDecimal.new("123.0"), type.cast(123.0)
end
def test_type_cast_from_float_with_unspecified_precision
type = Decimal.new
- assert_equal 22.68.to_d, type.type_cast_from_user(22.68)
+ assert_equal 22.68.to_d, type.cast(22.68)
end
def test_type_cast_decimal_from_rational_with_precision
type = Decimal.new(precision: 2)
- assert_equal BigDecimal("0.33"), type.type_cast_from_user(Rational(1, 3))
+ assert_equal BigDecimal("0.33"), type.cast(Rational(1, 3))
end
def test_type_cast_decimal_from_rational_without_precision_defaults_to_18_36
type = Decimal.new
- assert_equal BigDecimal("0.333333333333333333E0"), type.type_cast_from_user(Rational(1, 3))
+ assert_equal BigDecimal("0.333333333333333333E0"), type.cast(Rational(1, 3))
end
def test_type_cast_decimal_from_object_responding_to_d
@@ -36,7 +36,7 @@ module ActiveRecord
BigDecimal.new("1")
end
type = Decimal.new
- assert_equal BigDecimal("1"), type.type_cast_from_user(value)
+ assert_equal BigDecimal("1"), type.cast(value)
end
def test_changed?
diff --git a/activerecord/test/cases/type/integer_test.rb b/activerecord/test/cases/type/integer_test.rb
index 1e836f2142..84fb05dd8e 100644
--- a/activerecord/test/cases/type/integer_test.rb
+++ b/activerecord/test/cases/type/integer_test.rb
@@ -6,45 +6,45 @@ module ActiveRecord
class IntegerTest < ActiveRecord::TestCase
test "simple values" do
type = Type::Integer.new
- assert_equal 1, type.type_cast_from_user(1)
- assert_equal 1, type.type_cast_from_user('1')
- assert_equal 1, type.type_cast_from_user('1ignore')
- assert_equal 0, type.type_cast_from_user('bad1')
- assert_equal 0, type.type_cast_from_user('bad')
- assert_equal 1, type.type_cast_from_user(1.7)
- assert_equal 0, type.type_cast_from_user(false)
- assert_equal 1, type.type_cast_from_user(true)
- assert_nil type.type_cast_from_user(nil)
+ assert_equal 1, type.cast(1)
+ assert_equal 1, type.cast('1')
+ assert_equal 1, type.cast('1ignore')
+ assert_equal 0, type.cast('bad1')
+ assert_equal 0, type.cast('bad')
+ assert_equal 1, type.cast(1.7)
+ assert_equal 0, type.cast(false)
+ assert_equal 1, type.cast(true)
+ assert_nil type.cast(nil)
end
test "random objects cast to nil" do
type = Type::Integer.new
- assert_nil type.type_cast_from_user([1,2])
- assert_nil type.type_cast_from_user({1 => 2})
- assert_nil type.type_cast_from_user((1..2))
+ assert_nil type.cast([1,2])
+ assert_nil type.cast({1 => 2})
+ assert_nil type.cast((1..2))
end
test "casting ActiveRecord models" do
type = Type::Integer.new
firm = Firm.create(:name => 'Apple')
- assert_nil type.type_cast_from_user(firm)
+ assert_nil type.cast(firm)
end
test "casting objects without to_i" do
type = Type::Integer.new
- assert_nil type.type_cast_from_user(::Object.new)
+ assert_nil type.cast(::Object.new)
end
test "casting nan and infinity" do
type = Type::Integer.new
- assert_nil type.type_cast_from_user(::Float::NAN)
- assert_nil type.type_cast_from_user(1.0/0.0)
+ assert_nil type.cast(::Float::NAN)
+ assert_nil type.cast(1.0/0.0)
end
test "casting booleans for database" do
type = Type::Integer.new
- assert_equal 1, type.type_cast_for_database(true)
- assert_equal 0, type.type_cast_for_database(false)
+ assert_equal 1, type.serialize(true)
+ assert_equal 0, type.serialize(false)
end
test "changed?" do
@@ -60,53 +60,53 @@ module ActiveRecord
test "values below int min value are out of range" do
assert_raises(::RangeError) do
- Integer.new.type_cast_for_database(-2147483649)
+ Integer.new.serialize(-2147483649)
end
end
test "values above int max value are out of range" do
assert_raises(::RangeError) do
- Integer.new.type_cast_for_database(2147483648)
+ Integer.new.serialize(2147483648)
end
end
test "very small numbers are out of range" do
assert_raises(::RangeError) do
- Integer.new.type_cast_for_database(-9999999999999999999999999999999)
+ Integer.new.serialize(-9999999999999999999999999999999)
end
end
test "very large numbers are out of range" do
assert_raises(::RangeError) do
- Integer.new.type_cast_for_database(9999999999999999999999999999999)
+ Integer.new.serialize(9999999999999999999999999999999)
end
end
test "normal numbers are in range" do
type = Integer.new
- assert_equal(0, type.type_cast_for_database(0))
- assert_equal(-1, type.type_cast_for_database(-1))
- assert_equal(1, type.type_cast_for_database(1))
+ assert_equal(0, type.serialize(0))
+ assert_equal(-1, type.serialize(-1))
+ assert_equal(1, type.serialize(1))
end
test "int max value is in range" do
- assert_equal(2147483647, Integer.new.type_cast_for_database(2147483647))
+ assert_equal(2147483647, Integer.new.serialize(2147483647))
end
test "int min value is in range" do
- assert_equal(-2147483648, Integer.new.type_cast_for_database(-2147483648))
+ assert_equal(-2147483648, Integer.new.serialize(-2147483648))
end
test "columns with a larger limit have larger ranges" do
type = Integer.new(limit: 8)
- assert_equal(9223372036854775807, type.type_cast_for_database(9223372036854775807))
- assert_equal(-9223372036854775808, type.type_cast_for_database(-9223372036854775808))
+ assert_equal(9223372036854775807, type.serialize(9223372036854775807))
+ assert_equal(-9223372036854775808, type.serialize(-9223372036854775808))
assert_raises(::RangeError) do
- type.type_cast_for_database(-9999999999999999999999999999999)
+ type.serialize(-9999999999999999999999999999999)
end
assert_raises(::RangeError) do
- type.type_cast_for_database(9999999999999999999999999999999)
+ type.serialize(9999999999999999999999999999999)
end
end
diff --git a/activerecord/test/cases/type/string_test.rb b/activerecord/test/cases/type/string_test.rb
index 4d78f287f1..56e9bf434d 100644
--- a/activerecord/test/cases/type/string_test.rb
+++ b/activerecord/test/cases/type/string_test.rb
@@ -4,16 +4,16 @@ module ActiveRecord
class StringTypeTest < ActiveRecord::TestCase
test "type casting" do
type = Type::String.new
- assert_equal "t", type.type_cast_from_user(true)
- assert_equal "f", type.type_cast_from_user(false)
- assert_equal "123", type.type_cast_from_user(123)
+ assert_equal "t", type.cast(true)
+ assert_equal "f", type.cast(false)
+ assert_equal "123", type.cast(123)
end
test "values are duped coming out" do
s = "foo"
type = Type::String.new
- assert_not_same s, type.type_cast_from_user(s)
- assert_not_same s, type.type_cast_from_database(s)
+ assert_not_same s, type.cast(s)
+ assert_not_same s, type.deserialize(s)
end
test "string mutations are detected" do
diff --git a/activerecord/test/cases/type/unsigned_integer_test.rb b/activerecord/test/cases/type/unsigned_integer_test.rb
index 4b8e2fb518..f2c910eade 100644
--- a/activerecord/test/cases/type/unsigned_integer_test.rb
+++ b/activerecord/test/cases/type/unsigned_integer_test.rb
@@ -4,12 +4,12 @@ module ActiveRecord
module Type
class UnsignedIntegerTest < ActiveRecord::TestCase
test "unsigned int max value is in range" do
- assert_equal(4294967295, UnsignedInteger.new.type_cast_for_database(4294967295))
+ assert_equal(4294967295, UnsignedInteger.new.serialize(4294967295))
end
test "minus value is out of range" do
assert_raises(::RangeError) do
- UnsignedInteger.new.type_cast_for_database(-1)
+ UnsignedInteger.new.serialize(-1)
end
end
end
diff --git a/activerecord/test/cases/type_test.rb b/activerecord/test/cases/type_test.rb
new file mode 100644
index 0000000000..d45a9b3141
--- /dev/null
+++ b/activerecord/test/cases/type_test.rb
@@ -0,0 +1,39 @@
+require "cases/helper"
+
+class TypeTest < ActiveRecord::TestCase
+ setup do
+ @old_registry = ActiveRecord::Type.registry
+ ActiveRecord::Type.registry = ActiveRecord::Type::AdapterSpecificRegistry.new
+ end
+
+ teardown do
+ ActiveRecord::Type.registry = @old_registry
+ end
+
+ test "registering a new type" do
+ type = Struct.new(:args)
+ ActiveRecord::Type.register(:foo, type)
+
+ assert_equal type.new(:arg), ActiveRecord::Type.lookup(:foo, :arg)
+ end
+
+ test "looking up a type for a specific adapter" do
+ type = Struct.new(:args)
+ pgtype = Struct.new(:args)
+ ActiveRecord::Type.register(:foo, type, override: false)
+ ActiveRecord::Type.register(:foo, pgtype, adapter: :postgresql)
+
+ assert_equal type.new, ActiveRecord::Type.lookup(:foo, adapter: :sqlite)
+ assert_equal pgtype.new, ActiveRecord::Type.lookup(:foo, adapter: :postgresql)
+ end
+
+ test "lookup defaults to the current adapter" do
+ current_adapter = ActiveRecord::Base.connection.adapter_name.downcase.to_sym
+ type = Struct.new(:args)
+ adapter_type = Struct.new(:args)
+ ActiveRecord::Type.register(:foo, type, override: false)
+ ActiveRecord::Type.register(:foo, adapter_type, adapter: current_adapter)
+
+ assert_equal adapter_type.new, ActiveRecord::Type.lookup(:foo)
+ end
+end
diff --git a/activerecord/test/cases/types_test.rb b/activerecord/test/cases/types_test.rb
index 34b6f2e8a5..9b1859c2ce 100644
--- a/activerecord/test/cases/types_test.rb
+++ b/activerecord/test/cases/types_test.rb
@@ -5,38 +5,38 @@ module ActiveRecord
class TypesTest < ActiveRecord::TestCase
def test_type_cast_boolean
type = Type::Boolean.new
- assert type.type_cast_from_user('').nil?
- assert type.type_cast_from_user(nil).nil?
-
- assert type.type_cast_from_user(true)
- assert type.type_cast_from_user(1)
- assert type.type_cast_from_user('1')
- assert type.type_cast_from_user('t')
- assert type.type_cast_from_user('T')
- assert type.type_cast_from_user('true')
- assert type.type_cast_from_user('TRUE')
- assert type.type_cast_from_user('on')
- assert type.type_cast_from_user('ON')
- assert type.type_cast_from_user(' ')
- assert type.type_cast_from_user("\u3000\r\n")
- assert type.type_cast_from_user("\u0000")
- assert type.type_cast_from_user('SOMETHING RANDOM')
+ assert type.cast('').nil?
+ assert type.cast(nil).nil?
+
+ assert type.cast(true)
+ assert type.cast(1)
+ assert type.cast('1')
+ assert type.cast('t')
+ assert type.cast('T')
+ assert type.cast('true')
+ assert type.cast('TRUE')
+ assert type.cast('on')
+ assert type.cast('ON')
+ assert type.cast(' ')
+ assert type.cast("\u3000\r\n")
+ assert type.cast("\u0000")
+ assert type.cast('SOMETHING RANDOM')
# explicitly check for false vs nil
- assert_equal false, type.type_cast_from_user(false)
- assert_equal false, type.type_cast_from_user(0)
- assert_equal false, type.type_cast_from_user('0')
- assert_equal false, type.type_cast_from_user('f')
- assert_equal false, type.type_cast_from_user('F')
- assert_equal false, type.type_cast_from_user('false')
- assert_equal false, type.type_cast_from_user('FALSE')
- assert_equal false, type.type_cast_from_user('off')
- assert_equal false, type.type_cast_from_user('OFF')
+ assert_equal false, type.cast(false)
+ assert_equal false, type.cast(0)
+ assert_equal false, type.cast('0')
+ assert_equal false, type.cast('f')
+ assert_equal false, type.cast('F')
+ assert_equal false, type.cast('false')
+ assert_equal false, type.cast('FALSE')
+ assert_equal false, type.cast('off')
+ assert_equal false, type.cast('OFF')
end
def test_type_cast_float
type = Type::Float.new
- assert_equal 1.0, type.type_cast_from_user("1")
+ assert_equal 1.0, type.cast("1")
end
def test_changing_float
@@ -50,54 +50,54 @@ module ActiveRecord
def test_type_cast_binary
type = Type::Binary.new
- assert_equal nil, type.type_cast_from_user(nil)
- assert_equal "1", type.type_cast_from_user("1")
- assert_equal 1, type.type_cast_from_user(1)
+ assert_equal nil, type.cast(nil)
+ assert_equal "1", type.cast("1")
+ assert_equal 1, type.cast(1)
end
def test_type_cast_time
type = Type::Time.new
- assert_equal nil, type.type_cast_from_user(nil)
- assert_equal nil, type.type_cast_from_user('')
- assert_equal nil, type.type_cast_from_user('ABC')
+ assert_equal nil, type.cast(nil)
+ assert_equal nil, type.cast('')
+ assert_equal nil, type.cast('ABC')
time_string = Time.now.utc.strftime("%T")
- assert_equal time_string, type.type_cast_from_user(time_string).strftime("%T")
+ assert_equal time_string, type.cast(time_string).strftime("%T")
end
def test_type_cast_datetime_and_timestamp
type = Type::DateTime.new
- assert_equal nil, type.type_cast_from_user(nil)
- assert_equal nil, type.type_cast_from_user('')
- assert_equal nil, type.type_cast_from_user(' ')
- assert_equal nil, type.type_cast_from_user('ABC')
+ assert_equal nil, type.cast(nil)
+ assert_equal nil, type.cast('')
+ assert_equal nil, type.cast(' ')
+ assert_equal nil, type.cast('ABC')
datetime_string = Time.now.utc.strftime("%FT%T")
- assert_equal datetime_string, type.type_cast_from_user(datetime_string).strftime("%FT%T")
+ assert_equal datetime_string, type.cast(datetime_string).strftime("%FT%T")
end
def test_type_cast_date
type = Type::Date.new
- assert_equal nil, type.type_cast_from_user(nil)
- assert_equal nil, type.type_cast_from_user('')
- assert_equal nil, type.type_cast_from_user(' ')
- assert_equal nil, type.type_cast_from_user('ABC')
+ assert_equal nil, type.cast(nil)
+ assert_equal nil, type.cast('')
+ assert_equal nil, type.cast(' ')
+ assert_equal nil, type.cast('ABC')
date_string = Time.now.utc.strftime("%F")
- assert_equal date_string, type.type_cast_from_user(date_string).strftime("%F")
+ assert_equal date_string, type.cast(date_string).strftime("%F")
end
def test_type_cast_duration_to_integer
type = Type::Integer.new
- assert_equal 1800, type.type_cast_from_user(30.minutes)
- assert_equal 7200, type.type_cast_from_user(2.hours)
+ assert_equal 1800, type.cast(30.minutes)
+ assert_equal 7200, type.cast(2.hours)
end
def test_string_to_time_with_timezone
[:utc, :local].each do |zone|
with_timezone_config default: zone do
type = Type::DateTime.new
- assert_equal Time.utc(2013, 9, 4, 0, 0, 0), type.type_cast_from_user("Wed, 04 Sep 2013 03:00:00 EAT")
+ assert_equal Time.utc(2013, 9, 4, 0, 0, 0), type.cast("Wed, 04 Sep 2013 03:00:00 EAT")
end
end
end
@@ -110,7 +110,7 @@ module ActiveRecord
def test_attributes_which_are_invalid_for_database_can_still_be_reassigned
type_which_cannot_go_to_the_database = Type::Value.new
- def type_which_cannot_go_to_the_database.type_cast_for_database(*)
+ def type_which_cannot_go_to_the_database.serialize(*)
raise
end
klass = Class.new(ActiveRecord::Base) do
diff --git a/activerecord/test/migrations/missing/1000_people_have_middle_names.rb b/activerecord/test/migrations/missing/1000_people_have_middle_names.rb
index 9fd495b97c..4b83d61beb 100644
--- a/activerecord/test/migrations/missing/1000_people_have_middle_names.rb
+++ b/activerecord/test/migrations/missing/1000_people_have_middle_names.rb
@@ -6,4 +6,4 @@ class PeopleHaveMiddleNames < ActiveRecord::Migration
def self.down
remove_column "people", "middle_name"
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/migrations/missing/1_people_have_last_names.rb b/activerecord/test/migrations/missing/1_people_have_last_names.rb
index 81af5fef5e..68209f3ce9 100644
--- a/activerecord/test/migrations/missing/1_people_have_last_names.rb
+++ b/activerecord/test/migrations/missing/1_people_have_last_names.rb
@@ -6,4 +6,4 @@ class PeopleHaveLastNames < ActiveRecord::Migration
def self.down
remove_column "people", "last_name"
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/migrations/missing/3_we_need_reminders.rb b/activerecord/test/migrations/missing/3_we_need_reminders.rb
index d5e71ce8ef..25bb49cb32 100644
--- a/activerecord/test/migrations/missing/3_we_need_reminders.rb
+++ b/activerecord/test/migrations/missing/3_we_need_reminders.rb
@@ -9,4 +9,4 @@ class WeNeedReminders < ActiveRecord::Migration
def self.down
drop_table "reminders"
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/migrations/missing/4_innocent_jointable.rb b/activerecord/test/migrations/missing/4_innocent_jointable.rb
index 21c9ca5328..002a1bf2a6 100644
--- a/activerecord/test/migrations/missing/4_innocent_jointable.rb
+++ b/activerecord/test/migrations/missing/4_innocent_jointable.rb
@@ -9,4 +9,4 @@ class InnocentJointable < ActiveRecord::Migration
def self.down
drop_table "people_reminders"
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/migrations/rename/1_we_need_things.rb b/activerecord/test/migrations/rename/1_we_need_things.rb
index cdbe0b1679..f5484ac54f 100644
--- a/activerecord/test/migrations/rename/1_we_need_things.rb
+++ b/activerecord/test/migrations/rename/1_we_need_things.rb
@@ -8,4 +8,4 @@ class WeNeedThings < ActiveRecord::Migration
def self.down
drop_table "things"
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/migrations/rename/2_rename_things.rb b/activerecord/test/migrations/rename/2_rename_things.rb
index d441b71fc9..533a113ea8 100644
--- a/activerecord/test/migrations/rename/2_rename_things.rb
+++ b/activerecord/test/migrations/rename/2_rename_things.rb
@@ -6,4 +6,4 @@ class RenameThings < ActiveRecord::Migration
def self.down
rename_table "awesome_things", "things"
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/migrations/valid/2_we_need_reminders.rb b/activerecord/test/migrations/valid/2_we_need_reminders.rb
index d5e71ce8ef..25bb49cb32 100644
--- a/activerecord/test/migrations/valid/2_we_need_reminders.rb
+++ b/activerecord/test/migrations/valid/2_we_need_reminders.rb
@@ -9,4 +9,4 @@ class WeNeedReminders < ActiveRecord::Migration
def self.down
drop_table "reminders"
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/migrations/valid/3_innocent_jointable.rb b/activerecord/test/migrations/valid/3_innocent_jointable.rb
index 21c9ca5328..002a1bf2a6 100644
--- a/activerecord/test/migrations/valid/3_innocent_jointable.rb
+++ b/activerecord/test/migrations/valid/3_innocent_jointable.rb
@@ -9,4 +9,4 @@ class InnocentJointable < ActiveRecord::Migration
def self.down
drop_table "people_reminders"
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb b/activerecord/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb
index d5e71ce8ef..25bb49cb32 100644
--- a/activerecord/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb
+++ b/activerecord/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb
@@ -9,4 +9,4 @@ class WeNeedReminders < ActiveRecord::Migration
def self.down
drop_table "reminders"
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb b/activerecord/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb
index 21c9ca5328..002a1bf2a6 100644
--- a/activerecord/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb
+++ b/activerecord/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb
@@ -9,4 +9,4 @@ class InnocentJointable < ActiveRecord::Migration
def self.down
drop_table "people_reminders"
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/models/admin.rb b/activerecord/test/models/admin.rb
index 00e69fbed8..a38e3f4846 100644
--- a/activerecord/test/models/admin.rb
+++ b/activerecord/test/models/admin.rb
@@ -2,4 +2,4 @@ module Admin
def self.table_name_prefix
'admin_'
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/models/admin/account.rb b/activerecord/test/models/admin/account.rb
index 46de28aae1..bd23192d20 100644
--- a/activerecord/test/models/admin/account.rb
+++ b/activerecord/test/models/admin/account.rb
@@ -1,3 +1,3 @@
class Admin::Account < ActiveRecord::Base
has_many :users
-end \ No newline at end of file
+end
diff --git a/activerecord/test/models/binary.rb b/activerecord/test/models/binary.rb
index 950c459199..39b2f5090a 100644
--- a/activerecord/test/models/binary.rb
+++ b/activerecord/test/models/binary.rb
@@ -1,2 +1,2 @@
class Binary < ActiveRecord::Base
-end \ No newline at end of file
+end
diff --git a/activerecord/test/models/event.rb b/activerecord/test/models/event.rb
index 99fa0feeb7..365ab32b0b 100644
--- a/activerecord/test/models/event.rb
+++ b/activerecord/test/models/event.rb
@@ -1,3 +1,3 @@
class Event < ActiveRecord::Base
validates_uniqueness_of :title
-end \ No newline at end of file
+end
diff --git a/activerecord/test/models/guid.rb b/activerecord/test/models/guid.rb
index 9208dc28fa..05653ba498 100644
--- a/activerecord/test/models/guid.rb
+++ b/activerecord/test/models/guid.rb
@@ -1,2 +1,2 @@
class Guid < ActiveRecord::Base
-end \ No newline at end of file
+end
diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb
index 366c70f902..30545bdcd7 100644
--- a/activerecord/test/models/pirate.rb
+++ b/activerecord/test/models/pirate.rb
@@ -89,4 +89,4 @@ class FamousPirate < ActiveRecord::Base
self.table_name = 'pirates'
has_many :famous_ships
validates_presence_of :catchphrase, on: :conference
-end \ No newline at end of file
+end
diff --git a/activerecord/test/schema/postgresql_specific_schema.rb b/activerecord/test/schema/postgresql_specific_schema.rb
index 55360b9aa2..77d2f7fda2 100644
--- a/activerecord/test/schema/postgresql_specific_schema.rb
+++ b/activerecord/test/schema/postgresql_specific_schema.rb
@@ -2,7 +2,7 @@ ActiveRecord::Schema.define do
%w(postgresql_times postgresql_oids defaults postgresql_timestamp_with_zones
postgresql_partitioned_table postgresql_partitioned_table_parent).each do |table_name|
- execute "DROP TABLE IF EXISTS #{quote_table_name table_name}"
+ drop_table table_name, if_exists: true
end
execute 'DROP SEQUENCE IF EXISTS companies_nonstd_seq CASCADE'