create_table
просто дает, если дан блок.
def create_table(table_name, **options)
td = create_table_definition(table_name, options)
# ...
yield td if block_given?
# ...
result = execute schema_creation.accept td
# ...
end
create_table_definition
создает экземпляр ActiveRecord::ConnectionAdapters::TableDefinition
.
Представляет схему таблицы SQL абстрактным способом. Этот класс предоставляет методы для управления представлением схемы.
На самом деле это не черные маги c. Это объект DSL, который представляет таблицу и ее столбцы и, в конце концов, создает строку SQL из структуры данных.
Когда вы затем вызываете метод column
(и его делегаты, к которым я доберусь) в определении таблицы внутри блока, который вы фактически изменяете объекту td, переданный в аргументах блоку, добавляя объекты ColumnDefinition в список столбцов. Помните, что Ruby передается по ссылке.
Как, например, метод извлекает переменную (и) параметра блока?
Они этого не делают. yield
, как и все остальное в Ruby, является выражением и возвращает значение, возвращаемое блоком. Этот метод даже не заботится о возвращаемом значении, поскольку все о побочных эффектах. Любые аргументы, передаваемые в блок, являются локальными для этой области, и локальные переменные будут собираться мусором после завершения блока, если на них нет ссылок вне блока.
Имеет ли ActiveRecord :: Migration, для запроса столбцов таблицы с опциями перезапись method_missing?
Нет. method_missing
здесь не используется. Единственное задействованное метапрограммирование - это модуль ColumnMethods , который определяет методы ярлыков, используемые для определения столбцов:
module ActiveRecord
module ConnectionAdapters #:nodoc:
# ...
module ColumnMethods
# Appends a primary key definition to the table definition.
# Can be called multiple times, but this is probably not a good idea.
def primary_key(name, type = :primary_key, **options)
column(name, type, options.merge(primary_key: true))
end
# Appends a column or columns of a specified type.
#
# t.string(:goat)
# t.string(:goat, :sheep)
#
# See TableDefinition#column
[
:bigint,
:binary,
:boolean,
:date,
:datetime,
:decimal,
:float,
:integer,
:string,
:text,
:time,
:timestamp,
:virtual,
].each do |column_type|
module_eval <<-CODE, __FILE__, __LINE__ + 1
def #{column_type}(*args, **options)
args.each { |name| column(name, :#{column_type}, options) }
end
CODE
end
alias_method :numeric, :decimal
end
# ...
end
end
Фактические драйверы базы данных, такие как ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
и MysqlAdapter
, добавляют больше типов в этот список, такой как json.
Он также фактически не запрашивает таблицу, поскольку он еще не существует, когда выполняется блок.