модуль ActiveRecord::ModelSchema::ClassMethods
Общедоступные методы экземпляров
# File activerecord/lib/active_record/model_schema.rb, line 469 def column_defaults load_schema @column_defaults ||= _default_attributes.deep_dup.to_hash.freeze end
Возвращает хэш, где ключами являются имена столбцов, а значениями — значения по умолчанию при создании объекта Active Record для этой таблицы.
# File activerecord/lib/active_record/model_schema.rb, line 460
def column_for_attribute(name)
name = name.to_s
columns_hash.fetch(name) do
ConnectionAdapters::NullColumn.new(name)
end
end Возвращает объект столбца для указанного атрибута. Возвращает ActiveRecord::ConnectionAdapters::NullColumn если атрибут с указанным именем не существует.
class Person < ActiveRecord::Base end person = Person.new person.column_for_attribute(:name) # the result depends on the ConnectionAdapter # => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...> person.column_for_attribute(:nothing) # => #<ActiveRecord::ConnectionAdapters::NullColumn:0xXXX @name=nil, @sql_type=nil, @cast_type=#<Type::Value>, ...>
# File activerecord/lib/active_record/model_schema.rb, line 480 def column_names @column_names ||= columns.map(&:name).freeze end
Возвращает массив имён столбцов в виде строк.
# File activerecord/lib/active_record/model_schema.rb, line 411 def columns load_schema @columns ||= columns_hash.values.freeze end
# File activerecord/lib/active_record/model_schema.rb, line 491
def content_columns
@content_columns ||= columns.reject do |c|
c.name == primary_key ||
c.name == inheritance_column ||
c.name.end_with?("_id", "_count")
end.freeze
end Возвращает массив объектов столбцов, из которого удалены первичный ключ, все столбцы, заканчивающиеся на «_id» или «_count», и столбцы, используемые для наследования по одной таблице.
# File activerecord/lib/active_record/model_schema.rb, line 305
def ignored_columns
if defined?(@ignored_columns)
@ignored_columns
else
superclass.ignored_columns
end
end Список имён столбцов, которые модель должна игнорировать. Для игнорируемых столбцов не будут определены аксессоры атрибутов, и они не будут указаны в запросах SQL.
# File activerecord/lib/active_record/model_schema.rb, line 344 def ignored_columns=(columns) reload_schema_from_cache @ignored_columns = columns.map(&:to_s).freeze end
Устанавливает имена столбцов, которые модель должна игнорировать. Для игнорируемых столбцов не будут определены аксессоры атрибутов, и они не будут указаны в запросах SQL.
Типичный сценарий использования этого метода — убедиться, что все ссылки на атрибут были удалены и развернуты до того, как будет развернута и запущена миграция для удаления столбца из базы данных. Такой двухэтапный подход к удалению столбцов гарантирует, что нет кода, который вызывает ошибки из-за кешированной схемы в памяти в момент запуска миграции схемы.
Например, для модели, где вы хотите удалить атрибут «category», сначала отметьте его как игнорируемый:
class Project < ActiveRecord::Base # schema: # id :bigint # name :string, limit: 255 # category :string, limit: 255 self.ignored_columns = [:category] end
Схема всё ещё содержит «category», но теперь модель её пропускает, поэтому любой метаданный код или кэширование схемы не будут пытаться использовать столбец:
Project.columns_hash["category"] => nil
Если вы обратитесь к этому атрибуту напрямую, вы получите ошибку, поэтому убедитесь, что все использования столбца удалены (автоматические тесты могут помочь вам найти все такие использования).
user = Project.create!(name: "First Project") user.category # => raises NoMethodError
# File activerecord/lib/active_record/model_schema.rb, line 389 def next_sequence_value connection.next_sequence_value(sequence_name) end
Возвращает следующее значение, которое будет использовано в качестве первичного ключа в операторе вставки.
# File activerecord/lib/active_record/model_schema.rb, line 383 def prefetch_primary_key? connection.prefetch_primary_key?(table_name) end
Определяет, следует ли выбирать значения первичного ключа из соответствующей последовательности перед оператором вставки.
# File activerecord/lib/active_record/model_schema.rb, line 286
def protected_environments
if defined?(@protected_environments)
@protected_environments
else
superclass.protected_environments
end
end Массив имён сред, где запрещены разрушающие действия. По умолчанию значение равно ["production"].
# File activerecord/lib/active_record/model_schema.rb, line 295 def protected_environments=(environments) @protected_environments = environments.map(&:to_s) end
Устанавливает массив имён сред, где запрещены разрушающие действия.
# File activerecord/lib/active_record/model_schema.rb, line 261 def quoted_table_name @quoted_table_name ||= connection.quote_table_name(table_name) end
Возвращает цитированное имя таблицы, используемое для построения SQL-запросов.
# File activerecord/lib/active_record/model_schema.rb, line 525 def reset_column_information connection.clear_cache! ([self] + descendants).each(&:undefine_attribute_methods) connection.schema_cache.clear_data_source_cache!(table_name) reload_schema_from_cache initialize_find_by_cache end
Сбрасывает всю кэшированную информацию о столбцах, что приведёт к их перезагрузке при следующем запросе.
Наиболее распространённый сценарий использования этого метода — в миграции, когда сразу после создания таблицы вы хотите заполнить её значениями по умолчанию, например:
class CreateJobLevels < ActiveRecord::Migration[7.0]
def up
create_table :job_levels do |t|
t.integer :id
t.string :name
t.timestamps
end
JobLevel.reset_column_information
%w{assistant executive manager director}.each do |type|
JobLevel.create(name: type)
end
end
def down
drop_table :job_levels
end
end
# File activerecord/lib/active_record/model_schema.rb, line 349
def sequence_name
if base_class?
@sequence_name ||= reset_sequence_name
else
(@sequence_name ||= nil) || base_class.sequence_name
end
end # File activerecord/lib/active_record/model_schema.rb, line 376 def sequence_name=(value) @sequence_name = value.to_s @explicit_sequence_name = true end
Устанавливает имя последовательности для генерации идентификаторов заданному значению или (если значение — nil или false) значению, возвращаемому заданным блоком. Это необходимо для Oracle и полезно для любых баз данных, которые полагаются на последовательности для генерации первичных ключей.
Если имя последовательности не задано явно при использовании Oracle, оно будет по умолчанию соответствовать обычному шаблону: #{имя_таблицы}_seq
Если имя последовательности не задано явно при использовании PostgreSQL, оно будет определено автоматически для вашего первичного ключа.
class Project < ActiveRecord::Base self.sequence_name = "projectseq" # default would have been "project_seq" end
# File activerecord/lib/active_record/model_schema.rb, line 394 def table_exists? connection.schema_cache.data_source_exists?(table_name) end
Указывает, существует ли таблица, связанная с этим классом
# File activerecord/lib/active_record/model_schema.rb, line 235 def table_name reset_table_name unless defined?(@table_name) @table_name end
Предполагает имя таблицы (в принудительно нижнем регистре) на основе имени класса в иерархии наследования, непосредственно унаследованного от ActiveRecord::Base. Таким образом, если иерархия выглядит как: Reply < Message < ActiveRecord::Base, то Message используется для определения имени таблицы даже при вызове на Reply. Правила для определения имени обрабатываются классом Inflector в Active Support, который знает почти все общие английские склонения. Вы можете добавлять новые склонения в config/initializers/inflections.rb.
Вложенным классам присваиваются имена таблиц, начинающиеся с единственного числа имени таблицы родителя. Вложенные модули не рассматриваются.
Примеры
class Invoice < ActiveRecord::Base end file class table_name invoice.rb Invoice invoices class Invoice < ActiveRecord::Base class Lineitem < ActiveRecord::Base end end file class table_name invoice.rb Invoice::Lineitem invoice_lineitems module Invoice class Lineitem < ActiveRecord::Base end end file class table_name invoice/lineitem.rb Invoice::Lineitem lineitems
Кроме того, префикс уровня класса table_name_prefix добавляется, а суффикс table_name_suffix добавляется. Таким образом, если у вас есть префикс «myapp_», то предполагаемое имя таблицы для класса Invoice становится «myapp_invoices». Invoice::Lineitem становится «myapp_invoice_lineitems».
Базовое имя, используемое для определения имени таблицы, — model_name Active Model Naming. В случае определения настраиваемого имени Active Model Name оно также используется для имени таблицы:
class PostRecord < ActiveRecord::Base
class << self
def model_name
ActiveModel::Name.new(self, nil, "Post")
end
end
end
PostRecord.table_name
# => "posts"
Также вы можете явно установить своё имя таблицы:
class Mouse < ActiveRecord::Base self.table_name = "mice" end
# File activerecord/lib/active_record/model_schema.rb, line 245
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
@predicate_builder = nil
end Явно устанавливает имя таблицы. Пример:
class Project < ActiveRecord::Base self.table_name = "project" end
# File activerecord/lib/active_record/model_schema.rb, line 436
def type_for_attribute(attr_name, &block)
attr_name = attr_name.to_s
attr_name = attribute_aliases[attr_name] || attr_name
if block
attribute_types.fetch(attr_name, &block)
else
attribute_types[attr_name]
end
end Возвращает тип атрибута с заданным именем после применения всех модификаторов. Этот метод является единственным надёжным источником информации о типах атрибутов модели. Данный метод обращается к базе данных и загружает схему модели, если это необходимо.
Значение, возвращаемое этим методом, реализует интерфейс, описанный в ActiveModel::Type::Value (хотя сам объект может не быть его подклассом).
attr_name Имя атрибута, для которого требуется получить тип. Должно быть строкой или символом.
Защищённые методы экземпляра
# File activerecord/lib/active_record/model_schema.rb, line 535 def initialize_load_schema_monitor @load_schema_monitor = Monitor.new end
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.