From 3fab9d8821bc73b28a76f27353cab34d49096ad2 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Sat, 7 Jun 2014 07:09:45 -0600 Subject: Rename `property` to `attribute` For consistency with https://github.com/rails/rails/pull/15557 --- .../attribute_methods/serialization.rb | 2 +- activerecord/lib/active_record/attributes.rb | 122 +++++++++++++++++++++ activerecord/lib/active_record/base.rb | 4 +- activerecord/lib/active_record/properties.rb | 122 --------------------- 4 files changed, 125 insertions(+), 125 deletions(-) create mode 100644 activerecord/lib/active_record/attributes.rb delete mode 100644 activerecord/lib/active_record/properties.rb (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb index 148fc9eae5..e749311268 100644 --- a/activerecord/lib/active_record/attribute_methods/serialization.rb +++ b/activerecord/lib/active_record/attribute_methods/serialization.rb @@ -62,7 +62,7 @@ module ActiveRecord if type.serialized? type = type.subtype end - property attr_name, Type::Serialized.new(type, coder) + attribute attr_name, Type::Serialized.new(type, coder) # merge new serialized attribute and create new hash to ensure that each class in inheritance hierarchy # has its own hash of own serialized attributes diff --git a/activerecord/lib/active_record/attributes.rb b/activerecord/lib/active_record/attributes.rb new file mode 100644 index 0000000000..9c80121d70 --- /dev/null +++ b/activerecord/lib/active_record/attributes.rb @@ -0,0 +1,122 @@ +module ActiveRecord + module Attributes # :nodoc: + extend ActiveSupport::Concern + + Type = ActiveRecord::Type + + included do + class_attribute :user_provided_columns, instance_accessor: false # :internal: + self.user_provided_columns = {} + end + + module ClassMethods + # 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. + # + # +name+ The name of the methods to define attribute methods for, and the column which + # this will persist to. + # + # +cast_type+ A type object that contains information about how to type cast the value. + # See the examples section for more information. + # + # ==== Options + # The options hash accepts the following options: + # + # +default+ is the default value that the column should use on a new record. + # + # ==== Examples + # + # The type detected by Active Record can be overriden. + # + # # db/schema.rb + # create_table :store_listings, force: true do |t| + # t.decimal :price_in_cents + # end + # + # # app/models/store_listing.rb + # class StoreListing < ActiveRecord::Base + # end + # + # store_listing = StoreListing.new(price_in_cents: '10.1') + # + # # before + # store_listing.price_in_cents # => BigDecimal.new(10.1) + # + # class StoreListing < ActiveRecord::Base + # attribute :price_in_cents, Type::Integer.new + # end + # + # # after + # 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 + # with values both from the database, and from your controllers. See + # `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 + # def type_cast(value) + # if value.include?('$') + # price_in_dollars = value.gsub(/\$/, '').to_f + # price_in_dollars * 100 + # else + # value.to_i + # end + # end + # end + # + # class StoreListing < ActiveRecord::Base + # attribute :price_in_cents, MoneyType.new + # end + # + # store_listing = StoreListing.new(price_in_cents: '$10.00') + # store_listing.price_in_cents # => 1000 + def attribute(name, cast_type, options = {}) + 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)) + end + + # Returns an array of column objects for the table associated with this class. + def columns + @columns ||= add_user_provided_columns(connection.schema_cache.columns(table_name)) + end + + # Returns a hash of column objects for the table associated with this class. + def columns_hash + @columns_hash ||= Hash[columns.map { |c| [c.name, c] }] + end + + def reset_column_information # :nodoc: + super + clear_caches_calculated_from_columns + end + + private + + def add_user_provided_columns(schema_columns) + existing_columns = schema_columns.map do |column| + user_provided_columns[column.name] || column + end + + existing_column_names = existing_columns.map(&:name) + new_columns = user_provided_columns.except(*existing_column_names).values + + existing_columns + new_columns + end + + def clear_caches_calculated_from_columns + @columns = nil + @columns_hash = nil + @column_types = nil + @column_defaults = nil + @raw_column_defaults = nil + @column_names = nil + @content_columns = nil + end + end + end +end diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 8b0fffcf06..47de62a59b 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -19,7 +19,7 @@ require 'active_record/errors' require 'active_record/log_subscriber' require 'active_record/explain_subscriber' require 'active_record/relation/delegation' -require 'active_record/properties' +require 'active_record/attributes' module ActiveRecord #:nodoc: # = Active Record @@ -322,7 +322,7 @@ module ActiveRecord #:nodoc: include Reflection include Serialization include Store - include Properties + include Attributes end ActiveSupport.run_load_hooks(:active_record, Base) diff --git a/activerecord/lib/active_record/properties.rb b/activerecord/lib/active_record/properties.rb deleted file mode 100644 index 48ee42aaca..0000000000 --- a/activerecord/lib/active_record/properties.rb +++ /dev/null @@ -1,122 +0,0 @@ -module ActiveRecord - module Properties # :nodoc: - extend ActiveSupport::Concern - - Type = ActiveRecord::Type - - included do - class_attribute :user_provided_columns, instance_accessor: false # :internal: - self.user_provided_columns = {} - end - - module ClassMethods - # Defines or overrides a property on this model. This allows customization of - # Active Record's type casting behavior, as well as adding support for user defined - # types. - # - # +name+ The name of the methods to define attribute methods for, and the column which - # this will persist to. - # - # +cast_type+ A type object that contains information about how to type cast the value. - # See the examples section for more information. - # - # ==== Options - # The options hash accepts the following options: - # - # +default+ is the default value that the column should use on a new record. - # - # ==== Examples - # - # The type detected by Active Record can be overriden. - # - # # db/schema.rb - # create_table :store_listings, force: true do |t| - # t.decimal :price_in_cents - # end - # - # # app/models/store_listing.rb - # class StoreListing < ActiveRecord::Base - # end - # - # store_listing = StoreListing.new(price_in_cents: '10.1') - # - # # before - # store_listing.price_in_cents # => BigDecimal.new(10.1) - # - # class StoreListing < ActiveRecord::Base - # property :price_in_cents, Type::Integer.new - # end - # - # # after - # 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 - # with values both from the database, and from your controllers. See - # `ActiveRecord::Properties::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 - # def type_cast(value) - # if value.include?('$') - # price_in_dollars = value.gsub(/\$/, '').to_f - # price_in_dollars * 100 - # else - # value.to_i - # end - # end - # end - # - # class StoreListing < ActiveRecord::Base - # property :price_in_cents, MoneyType.new - # end - # - # store_listing = StoreListing.new(price_in_cents: '$10.00') - # store_listing.price_in_cents # => 1000 - def property(name, cast_type, options = {}) - 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)) - end - - # Returns an array of column objects for the table associated with this class. - def columns - @columns ||= add_user_provided_columns(connection.schema_cache.columns(table_name)) - end - - # Returns a hash of column objects for the table associated with this class. - def columns_hash - @columns_hash ||= Hash[columns.map { |c| [c.name, c] }] - end - - def reset_column_information # :nodoc: - super - clear_caches_calculated_from_columns - end - - private - - def add_user_provided_columns(schema_columns) - existing_columns = schema_columns.map do |column| - user_provided_columns[column.name] || column - end - - existing_column_names = existing_columns.map(&:name) - new_columns = user_provided_columns.except(*existing_column_names).values - - existing_columns + new_columns - end - - def clear_caches_calculated_from_columns - @columns = nil - @columns_hash = nil - @column_types = nil - @column_defaults = nil - @raw_column_defaults = nil - @column_names = nil - @content_columns = nil - end - end - end -end -- cgit v1.2.3