aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/model_schema.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/model_schema.rb')
-rw-r--r--activerecord/lib/active_record/model_schema.rb155
1 files changed, 75 insertions, 80 deletions
diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb
index f691a8319d..76b3169411 100644
--- a/activerecord/lib/active_record/model_schema.rb
+++ b/activerecord/lib/active_record/model_schema.rb
@@ -70,7 +70,7 @@ module ActiveRecord
class_attribute :ignored_columns, instance_accessor: false
self.ignored_columns = [].freeze
- self.inheritance_column = 'type'
+ self.inheritance_column = "type"
delegate :type_for_attribute, to: :class
end
@@ -173,11 +173,11 @@ module ActiveRecord
end
def full_table_name_prefix #:nodoc:
- (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
+ (parents.detect { |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
end
def full_table_name_suffix #:nodoc:
- (parents.detect {|p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
+ (parents.detect { |p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
end
# Defines the name of the table column which will store the class name on single-table
@@ -249,7 +249,11 @@ module ActiveRecord
end
def attributes_builder # :nodoc:
- @attributes_builder ||= AttributeSet::Builder.new(attribute_types, primary_key)
+ @attributes_builder ||= AttributeSet::Builder.new(attribute_types, primary_key) do |name|
+ unless columns_hash.key?(name)
+ _default_attributes[name].dup
+ end
+ end
end
def columns_hash # :nodoc:
@@ -264,7 +268,11 @@ module ActiveRecord
def attribute_types # :nodoc:
load_schema
- @attribute_types ||= Hash.new(Type::Value.new)
+ @attribute_types ||= Hash.new(Type.default_value)
+ end
+
+ def yaml_encoder # :nodoc:
+ @yaml_encoder ||= AttributeSet::YAMLEncoder.new(attribute_types)
end
# Returns the type of the attribute with the given name, after applying
@@ -278,8 +286,12 @@ module ActiveRecord
#
# +attr_name+ The name of the attribute to retrieve the type for. Must be
# a string
- def type_for_attribute(attr_name)
- attribute_types[attr_name]
+ def type_for_attribute(attr_name, &block)
+ if block
+ attribute_types.fetch(attr_name, &block)
+ else
+ attribute_types[attr_name]
+ end
end
# Returns a hash where the keys are column names and the values are
@@ -301,7 +313,12 @@ module ActiveRecord
# Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
# and columns used for single table inheritance have been removed.
def content_columns
- @content_columns ||= columns.reject { |c| c.name == primary_key || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
+ @content_columns ||= columns.reject do |c|
+ c.name == primary_key ||
+ c.name == inheritance_column ||
+ c.name.end_with?("_id") ||
+ c.name.end_with?("_count")
+ end
end
# Resets all the cached information about columns, which will cause them
@@ -340,91 +357,69 @@ module ActiveRecord
private
- def schema_loaded?
- defined?(@columns_hash) && @columns_hash
- end
-
- def load_schema
- unless schema_loaded?
- load_schema!
+ def schema_loaded?
+ defined?(@columns_hash) && @columns_hash
end
- end
- def load_schema!
- @columns_hash = connection.schema_cache.columns_hash(table_name).except(*ignored_columns)
- @columns_hash.each do |name, column|
- warn_if_deprecated_type(column)
- define_attribute(
- name,
- connection.lookup_cast_type_from_column(column),
- default: column.default,
- user_provided_default: false
- )
+ def load_schema
+ unless schema_loaded?
+ load_schema!
+ end
end
- end
- def reload_schema_from_cache
- @arel_engine = nil
- @arel_table = nil
- @column_names = nil
- @attribute_types = nil
- @content_columns = nil
- @default_attributes = nil
- @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
- @attributes_builder = nil
- @columns = nil
- @columns_hash = nil
- @attribute_names = nil
- direct_descendants.each do |descendant|
- descendant.send(:reload_schema_from_cache)
+ def load_schema!
+ @columns_hash = connection.schema_cache.columns_hash(table_name).except(*ignored_columns)
+ @columns_hash.each do |name, column|
+ define_attribute(
+ name,
+ connection.lookup_cast_type_from_column(column),
+ default: column.default,
+ user_provided_default: false
+ )
+ end
end
- end
-
- # Guesses the table name, but does not decorate it with prefix and suffix information.
- def undecorated_table_name(class_name = base_class.name)
- table_name = class_name.to_s.demodulize.underscore
- pluralize_table_names ? table_name.pluralize : table_name
- end
- # Computes and returns a table name according to default conventions.
- def compute_table_name
- base = base_class
- if self == base
- # Nested classes are prefixed with singular parent table name.
- if parent < Base && !parent.abstract_class?
- contained = parent.table_name
- contained = contained.singularize if parent.pluralize_table_names
- contained += '_'
+ def reload_schema_from_cache
+ @arel_engine = nil
+ @arel_table = nil
+ @column_names = nil
+ @attribute_types = nil
+ @content_columns = nil
+ @default_attributes = nil
+ @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
+ @attributes_builder = nil
+ @columns = nil
+ @columns_hash = nil
+ @attribute_names = nil
+ @yaml_encoder = nil
+ direct_descendants.each do |descendant|
+ descendant.send(:reload_schema_from_cache)
end
+ end
- "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
- else
- # STI subclasses always use their superclass' table.
- base.table_name
+ # Guesses the table name, but does not decorate it with prefix and suffix information.
+ def undecorated_table_name(class_name = base_class.name)
+ table_name = class_name.to_s.demodulize.underscore
+ pluralize_table_names ? table_name.pluralize : table_name
end
- end
- def warn_if_deprecated_type(column)
- return if attributes_to_define_after_schema_loads.key?(column.name)
- if column.respond_to?(:oid) && column.sql_type.start_with?("point")
- if column.array?
- array_arguments = ", array: true"
+ # Computes and returns a table name according to default conventions.
+ def compute_table_name
+ base = base_class
+ if self == base
+ # Nested classes are prefixed with singular parent table name.
+ if parent < Base && !parent.abstract_class?
+ contained = parent.table_name
+ contained = contained.singularize if parent.pluralize_table_names
+ contained += "_"
+ end
+
+ "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
else
- array_arguments = ""
+ # STI subclasses always use their superclass' table.
+ base.table_name
end
- ActiveSupport::Deprecation.warn(<<-WARNING.strip_heredoc)
- The behavior of the `:point` type will be changing in Rails 5.1 to
- return a `Point` object, rather than an `Array`. If you'd like to
- keep the old behavior, you can add this line to #{self.name}:
-
- attribute :#{column.name}, :legacy_point#{array_arguments}
-
- If you'd like the new behavior today, you can add this line:
-
- attribute :#{column.name}, :point#{array_arguments}
- WARNING
end
- end
end
end
end