aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attributes.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/attributes.rb')
-rw-r--r--activerecord/lib/active_record/attributes.rb30
1 files changed, 19 insertions, 11 deletions
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))