module ActiveRecord::ModelSchema::ClassMethods
def column_defaults
Returns a hash where the keys are column names and the values are
def column_defaults @column_defaults ||= Hash[columns.map { |c| [c.name, c.default] }] end
def column_methods_hash #:nodoc:
is available.
and true as the value. This makes it possible to do O(1) lookups in respond_to? to check if a given method for attribute
Returns a hash of all the methods added to query each of the columns in the table with the name of the method as the key
def column_methods_hash #:nodoc: @dynamic_methods_hash ||= column_names.each_with_object(Hash.new(false)) do |attr, methods| attr_name = attr.to_s methods[attr.to_sym] = attr_name methods["#{attr}=".to_sym] = attr_name methods["#{attr}?".to_sym] = attr_name methods["#{attr}_before_type_cast".to_sym] = attr_name end end
def column_names
def column_names @column_names ||= columns.map { |column| column.name } end
def column_types # :nodoc:
def column_types # :nodoc: @column_types ||= decorate_columns(columns_hash.dup) end
def columns
def columns @columns ||= connection.schema_cache.columns(table_name).map do |col| col = col.dup col.primary = (col.name == primary_key) col end end
def columns_hash
def columns_hash @columns_hash ||= Hash[columns.map { |c| [c.name, c] }] end
def compute_table_name
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)}#{table_name_suffix}" else # STI subclasses always use their superclass' table. base.table_name end end
def content_columns
Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
def content_columns @content_columns ||= columns.reject { |c| c.primary || c.name =~ /(_id|_count)$/ || c.name == inheritance_column } end
def decorate_columns(columns_hash) # :nodoc:
def decorate_columns(columns_hash) # :nodoc: return if columns_hash.empty? @serialized_column_names ||= self.columns_hash.keys.find_all do |name| serialized_attributes.key?(name) end @serialized_column_names.each do |name| columns_hash[name] = AttributeMethods::Serialization::Type.new(columns_hash[name]) end @time_zone_column_names ||= self.columns_hash.find_all do |name, col| create_time_zone_conversion_attribute?(name, col) end.map!(&:first) @time_zone_column_names.each do |name| columns_hash[name] = AttributeMethods::TimeZoneConversion::Type.new(columns_hash[name]) end columns_hash end
def full_table_name_prefix #:nodoc:
def full_table_name_prefix #:nodoc: (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix end
def inheritance_column
your own model for something else, you can set +inheritance_column+:
inheritance with another column name, or to use the column +type+ in
reserved word inside Active Record. To be able to use single-table
The default inheritance column name is +type+, which means it's a
inheritance situations.
Defines the name of the table column which will store the class name on single-table
def inheritance_column (@inheritance_column ||= nil) || superclass.inheritance_column end
def inheritance_column=(value)
def inheritance_column=(value) @inheritance_column = value.to_s @explicit_inheritance_column = true end
def initialize_attributes(attributes, options = {}) #:nodoc:
serialization)
attributes when they are initialized. (e.g. attribute
This is a hook for use by modules that need to do extra stuff to
def initialize_attributes(attributes, options = {}) #:nodoc: attributes end
def quoted_table_name
def quoted_table_name @quoted_table_name ||= connection.quote_table_name(table_name) end
def reset_column_information
end
drop_table :job_levels
def down
end
end
JobLevel.create(name: type)
%w{assistant executive manager director}.each do |type|
JobLevel.reset_column_information
end
t.timestamps
t.string :name
t.integer :id
create_table :job_levels do |t|
def up
class CreateJobLevels < ActiveRecord::Migration
values, eg:
when just after creating a table you want to populate it with some default
The most common usage pattern for this method is probably in a migration,
to be reloaded on the next request.
Resets all the cached information about columns, which will cause them
def reset_column_information connection.clear_cache! undefine_attribute_methods connection.schema_cache.clear_table_cache!(table_name) if table_exists? @arel_engine = nil @column_defaults = nil @column_names = nil @columns = nil @columns_hash = nil @column_types = nil @content_columns = nil @dynamic_methods_hash = nil @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column @relation = nil @serialized_column_names = nil @time_zone_column_names = nil @cached_time_zone = nil end
def reset_sequence_name #:nodoc:
def reset_sequence_name #:nodoc: @explicit_sequence_name = false @sequence_name = connection.default_sequence_name(table_name, primary_key) end
def reset_table_name #:nodoc:
Computes the table name, (re)sets it internally, and returns it.
def reset_table_name #:nodoc: self.table_name = if abstract_class? superclass == Base ? nil : superclass.table_name elsif superclass.abstract_class? superclass.table_name || compute_table_name else compute_table_name end end
def sequence_name
def sequence_name if base_class == self @sequence_name ||= reset_sequence_name else (@sequence_name ||= nil) || base_class.sequence_name end end
def sequence_name=(value)
self.sequence_name = "projectseq" # default would have been "project_seq"
class Project < ActiveRecord::Base
will discover the sequence corresponding to your primary key for you.
If a sequence name is not explicitly set when using PostgreSQL, it
it will default to the commonly used pattern of: #{table_name}_seq
If a sequence name is not explicitly set when using Oracle or Firebird,
database which relies on sequences for primary key generation.
given block. This is required for Oracle and is useful for any
value, or (if the value is nil or false) to the value returned by the
Sets the name of the sequence to use when generating ids to the given
def sequence_name=(value) @sequence_name = value.to_s @explicit_sequence_name = true end
def table_exists?
def table_exists? connection.schema_cache.table_exists?(table_name) end
def table_name
end
end
"special_" + super
def self.table_name
class Post < ActiveRecord::Base
table name.) Example:
own computation. (Possibly using super to manipulate the default
Alternatively, you can override the table_name method to define your
end
self.table_name = "mice"
class Mouse < ActiveRecord::Base
You can also set your own table name explicitly:
Invoice::Lineitem becomes "myapp_invoice_lineitems".
the table name guess for an Invoice class becomes "myapp_invoices".
+table_name_suffix+ is appended. So if you have "myapp_" as a prefix,
Additionally, the class-level +table_name_prefix+ is prepended and the
invoice/lineitem.rb Invoice::Lineitem lineitems
file class table_name
end
end
class Lineitem < ActiveRecord::Base
module Invoice
invoice.rb Invoice::Lineitem invoice_lineitems
file class table_name
end
end
class Lineitem < ActiveRecord::Base
class Invoice < ActiveRecord::Base
invoice.rb Invoice invoices
file class table_name
end
class Invoice < ActiveRecord::Base
==== Examples
the parent's table name. Enclosing modules are not considered.
Nested classes are given table names prefixed by the singular form of
English inflections. You can add new inflections in config/initializers/inflections.rb.
are handled by the Inflector class in Active Support, which knows almost all common
to guess the table name even when called on Reply. The rules used to do the guess
looks like: Reply < Message < ActiveRecord::Base, then Message is used
inheritance hierarchy descending directly from ActiveRecord::Base. So if the hierarchy
Guesses the table name (in forced lower-case) based on the name of the class in the
def table_name reset_table_name unless defined?(@table_name) @table_name end
def table_name=(value)
You can also just define your own self.table_name method; see
end
self.table_name = "project"
class Project < ActiveRecord::Base
Sets the table name explicitly. Example:
def table_name=(value) value = value && value.to_s if defined?(@table_name) return if value == @table_name reset_column_information if connected? end @table_name = value @quoted_table_name = nil @arel_table = nil @sequence_name = nil unless defined?(@explicit_sequence_name) && @explicit_sequence_name @relation = Relation.new(self, arel_table) end
def undecorated_table_name(class_name = base_class.name)
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