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.rb40
1 files changed, 29 insertions, 11 deletions
diff --git a/activerecord/lib/active_record/attributes.rb b/activerecord/lib/active_record/attributes.rb
index 9c80121d70..aafb990bc1 100644
--- a/activerecord/lib/active_record/attributes.rb
+++ b/activerecord/lib/active_record/attributes.rb
@@ -6,10 +6,12 @@ module ActiveRecord
included do
class_attribute :user_provided_columns, instance_accessor: false # :internal:
+ class_attribute :user_provided_defaults, instance_accessor: false # :internal:
self.user_provided_columns = {}
+ self.user_provided_defaults = {}
end
- module ClassMethods
+ module ClassMethods # :nodoc:
# Defines or overrides a attribute on this model. This allows customization of
# Active Record's type casting behavior, as well as adding support for user defined
# types.
@@ -27,7 +29,7 @@ module ActiveRecord
#
# ==== Examples
#
- # The type detected by Active Record can be overriden.
+ # The type detected by Active Record can be overridden.
#
# # db/schema.rb
# create_table :store_listings, force: true do |t|
@@ -51,9 +53,9 @@ module ActiveRecord
# store_listing.price_in_cents # => 10
#
# Users may also define their own custom types, as long as they respond to the methods
- # defined on the value type. The `type_cast` method on your type object will be called
+ # defined on the value type. The +type_cast+ method on your type object will be called
# with values both from the database, and from your controllers. See
- # `ActiveRecord::Attributes::Type::Value` for the expected API. It is recommended that your
+ # +ActiveRecord::Attributes::Type::Value+ for the expected API. It is recommended that your
# type objects inherit from an existing type, or the base value type.
#
# class MoneyType < ActiveRecord::Type::Integer
@@ -77,7 +79,11 @@ module ActiveRecord
name = name.to_s
clear_caches_calculated_from_columns
# Assign a new hash to ensure that subclasses do not share a hash
- self.user_provided_columns = user_provided_columns.merge(name => connection.new_column(name, options[:default], cast_type))
+ self.user_provided_columns = user_provided_columns.merge(name => cast_type)
+
+ if options.key?(:default)
+ self.user_provided_defaults = user_provided_defaults.merge(name => options[:default])
+ end
end
# Returns an array of column objects for the table associated with this class.
@@ -99,23 +105,35 @@ module ActiveRecord
def add_user_provided_columns(schema_columns)
existing_columns = schema_columns.map do |column|
- user_provided_columns[column.name] || column
+ new_type = user_provided_columns[column.name]
+ if new_type
+ column.with_type(new_type)
+ else
+ column
+ end
end
existing_column_names = existing_columns.map(&:name)
- new_columns = user_provided_columns.except(*existing_column_names).values
+ new_columns = user_provided_columns.except(*existing_column_names).map do |(name, type)|
+ connection.new_column(name, nil, type)
+ end
existing_columns + new_columns
end
def clear_caches_calculated_from_columns
+ @arel_table = nil
+ @attributes_builder = nil
+ @column_names = nil
+ @column_types = nil
@columns = nil
@columns_hash = nil
- @column_types = nil
- @column_defaults = nil
- @raw_column_defaults = nil
- @column_names = nil
@content_columns = nil
+ @default_attributes = nil
+ end
+
+ def raw_default_values
+ super.merge(user_provided_defaults)
end
end
end