diff options
Diffstat (limited to 'activerecord/lib/active_record/attributes.rb')
-rw-r--r-- | activerecord/lib/active_record/attributes.rb | 40 |
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 |