Spec-Zone.ru › Ruby on Rails 7.1

модуль ActiveRecord::Persistence::ClassMethods

Общедоступные методы экземпляров

build(attributes = nil, &block) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 82
def build(attributes = nil, &block)
  if attributes.is_a?(Array)
    attributes.collect { |attr| build(attr, &block) }
  else
    new(attributes, &block)
  end
end

Создаёт объект (или несколько объектов) и возвращает либо созданный объект, либо список созданных объектов.

Параметр attributes может быть либо Hash, либо Array массивом хэшей. Эти хэши описывают атрибуты объектов, которые должны быть созданы.

Примеры

# Build a single new object
User.build(first_name: 'Jamie')

# Build an Array of new objects
User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])

# Build a single object and pass it into a block to set other attributes.
User.build(first_name: 'Jamie') do |u|
  u.is_admin = false
end

# Building an Array of new objects using a block, where the block is executed for each object:
User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
  u.is_admin = false
end
create(attributes = nil, &block) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 33
def create(attributes = nil, &block)
  if attributes.is_a?(Array)
    attributes.collect { |attr| create(attr, &block) }
  else
    object = new(attributes, &block)
    object.save
    object
  end
end

Создаёт объект (или несколько объектов) и сохраняет его в базе данных, если валидация пройдена. Результирующий объект возвращается независимо от успешного сохранения в базе данных.

Параметр attributes может быть либо Hash, либо Array массивом хэшей. Эти хэши описывают атрибуты объектов, которые должны быть созданы.

Примеры

# Create a single new object
User.create(first_name: 'Jamie')

# Create an Array of new objects
User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])

# Create a single object and pass it into a block to set other attributes.
User.create(first_name: 'Jamie') do |u|
  u.is_admin = false
end

# Creating an Array of new objects using a block, where the block is executed for each object:
User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
  u.is_admin = false
end
create!(attributes = nil, &block) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 50
def create!(attributes = nil, &block)
  if attributes.is_a?(Array)
    attributes.collect { |attr| create!(attr, &block) }
  else
    object = new(attributes, &block)
    object.save!
    object
  end
end

Создаёт объект (или несколько объектов) и сохраняет его в базе данных, если валидация пройдена. Вызывает исключение RecordInvalid, если валидация не пройдена, в отличие от Base#create.

Параметр attributes может быть либо Hash, либо Array массивом хэшей. Эти хэши описывают атрибуты объекта или нескольких объектов, если передан Array массив хэшей.

delete(id_or_array) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 565
def delete(id_or_array)
  delete_by(primary_key => id_or_array)
end

Удаляет строку с первичным ключом, соответствующим аргументу id, используя SQL DELETE оператор и возвращает количество удалённых строк. Объекты Active Record не создаются, поэтому обратные вызовы объекта не выполняются, включая любые :dependent параметры ассоциации.

Вы можете удалить несколько строк одновременно, передав Array массив id.

Примечание: Хотя часто намного быстрее, чем альтернатива destroy, пропуск обратных вызовов может обойти логику вашего приложения, которая обеспечивает целостность ссылок или выполняет другие важные задачи.

Примеры

# Delete a single row
Todo.delete(1)

# Delete multiple rows
Todo.delete([2,3,4])
destroy(id) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 533
def destroy(id)
  multiple_ids = if composite_primary_key?
    id.first.is_a?(Array)
  else
    id.is_a?(Array)
  end

  if multiple_ids
    find(id).each(&:destroy)
  else
    find(id).destroy
  end
end

Уничтожает объект (или несколько объектов), у которого задан id. Сначала создаётся объект, поэтому все обратные вызовы и фильтры запускаются до удаления объекта. Этот метод менее эффективен, чем delete, но позволяет запускать методы очистки и другие действия.

По существу, этот метод находит объект (или несколько объектов) с заданным id, создаёт новый объект из атрибутов и затем вызывает destroy для него.

Параметры

  • id - Это должен быть id или массив id, которые необходимо уничтожить.

Примеры

# Destroy a single object
Todo.destroy(1)

# Destroy multiple objects
todos = [1,2,3]
Todo.destroy(todos)
insert(attributes, returning: nil, unique_by: nil, record_timestamps: nil) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 96
def insert(attributes, returning: nil, unique_by: nil, record_timestamps: nil)
  insert_all([ attributes ], returning: returning, unique_by: unique_by, record_timestamps: record_timestamps)
end

Вставляет одну запись в базу данных в одном SQL операторе INSERT. Он не создаёт модели и не запускает обратные вызовы или валидацию Active Record. Однако значения, переданные через Active Record, проходят типы приведения и сериализацию.

См. insert_all для документации.

insert!(attributes, returning: nil, record_timestamps: nil) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 185
def insert!(attributes, returning: nil, record_timestamps: nil)
  insert_all!([ attributes ], returning: returning, record_timestamps: record_timestamps)
end

Вставляет одну запись в базу данных в одном SQL операторе INSERT. Он не создаёт модели и не запускает обратные вызовы или валидацию Active Record. Однако значения, переданные через Active Record, проходят типы приведения и сериализацию.

См. insert_all! для более подробной информации.

insert_all(attributes, returning: nil, unique_by: nil, record_timestamps: nil) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 175
def insert_all(attributes, returning: nil, unique_by: nil, record_timestamps: nil)
  InsertAll.new(self, attributes, on_duplicate: :skip, returning: returning, unique_by: unique_by, record_timestamps: record_timestamps).execute
end

Вставляет несколько записей в базу данных в одном SQL операторе INSERT. Он не создаёт модели и не запускает обратные вызовы или валидацию Active Record. Однако значения, переданные через Active Record, проходят типы приведения и сериализацию.

Параметр attributes — это Array массив хэшей. Каждый Hash определяет атрибуты для одной строки и должен иметь одинаковые ключи.

Строки считаются уникальными по каждому уникальному индексу в таблице. Любые дублирующие строки пропускаются. Замените с помощью :unique_by (см. ниже).

Возвращает ActiveRecord::Result со своим содержимым на основе :returning (см. ниже).

Параметры

:returning

(только PostgreSQL) Массив атрибутов, которые нужно вернуть для всех успешно вставленных записей, по умолчанию это первичный ключ. Передайте returning: %w[ id name ] для id и имени или returning: false чтобы полностью пропустить подлежащий RETURNING SQL-оператор.

Вы также можете передать SQL-строку, если вам нужен больший контроль над возвращаемыми значениями (например, returning: Arel.sql("id, name as new_name")).

:unique_by

(только PostgreSQL и SQLite) По умолчанию строки считаются уникальными по каждому уникальному индексу в таблице. Любые дублирующие строки пропускаются.

Для пропуска строк в соответствии с одним уникальным индексом передайте :unique_by.

Рассмотрим модель Book, где дублирование ISBN не имеет смысла, но если какая-либо строка имеет существующий id или не уникальна по другому уникальному индексу, возникает ActiveRecord::RecordNotUnique.

Уникальные индексы могут быть определены по столбцам или имени:

unique_by: :isbn
unique_by: %i[ author_id name ]
unique_by: :index_books_on_isbn
:record_timestamps

По умолчанию автоматическая установка временных столбцов контролируется конфигурацией модели record_timestamps, что соответствует обычному поведению.

Для того, чтобы переопределить это и принудительно установить временные столбцы каким-либо образом, передайте :record_timestamps:

record_timestamps: true  # Always set timestamps automatically
record_timestamps: false # Never set timestamps automatically

Поскольку он зависит от информации индекса из базы данных, :unique_by рекомендуется использовать в сочетании с кэшем схемы Active Record.

Пример

# Insert records and skip inserting any duplicates.
# Here "Eloquent Ruby" is skipped because its id is not unique.

Book.insert_all([
  { id: 1, title: "Rework", author: "David" },
  { id: 1, title: "Eloquent Ruby", author: "Russ" }
])

# insert_all works on chained scopes, and you can use create_with
# to set default attributes for all inserted records.

author.books.create_with(created_at: Time.now).insert_all([
  { id: 1, title: "Rework" },
  { id: 2, title: "Eloquent Ruby" }
])
insert_all!(attributes, returning: nil, record_timestamps: nil) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 242
def insert_all!(attributes, returning: nil, record_timestamps: nil)
  InsertAll.new(self, attributes, on_duplicate: :raise, returning: returning, record_timestamps: record_timestamps).execute
end

Вставляет несколько записей в базу данных в одном SQL-выражении INSERT. Оно не создаёт экземпляры моделей и не запускает обратные вызовы или валидацию Active Record. Хотя значения, переданные в него, проходят через преобразование типов и сериализацию Active Record.

Параметр attributes — это Array словарей. Каждый Hash определяет атрибуты для одной строки и должен иметь одинаковые ключи.

Вызывает ActiveRecord::RecordNotUnique, если какие-либо строки нарушают уникальный индекс в таблице. В этом случае никакие строки не вставляются.

Чтобы пропустить дубликаты строк, см. insert_all. Чтобы заменить их, см. upsert_all.

Возвращает ActiveRecord::Result с содержанием, основанным на :returning (см. ниже).

Параметры

:returning

(Только PostgreSQL) Массив атрибутов, которые нужно вернуть для всех успешно вставленных записей, по умолчанию — первичный ключ. Передайте returning: %w[ id name ] для id и name или returning: false, чтобы полностью исключить подлежащий RETURNING SQL-оператор.

Вы также можете передать строку SQL, если вам нужен больший контроль над возвращаемыми значениями (например, returning: Arel.sql("id, name as new_name")).

:record_timestamps

По умолчанию автоматическое установка значений столбцов со временем управляется конфигурацией модели record_timestamps, соответствующей типичному поведению.

Чтобы переопределить это и принудительно установить столбцы со временем одним или другим способом, передайте :record_timestamps:

record_timestamps: true  # Always set timestamps automatically
record_timestamps: false # Never set timestamps automatically

Примеры

# Insert multiple records
Book.insert_all!([
  { title: "Rework", author: "David" },
  { title: "Eloquent Ruby", author: "Russ" }
])

# Raises ActiveRecord::RecordNotUnique because "Eloquent Ruby"
# does not have a unique id.
Book.insert_all!([
  { id: 1, title: "Rework", author: "David" },
  { id: 1, title: "Eloquent Ruby", author: "Russ" }
])
instantiate(attributes, column_types = {}, &block) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 376
def instantiate(attributes, column_types = {}, &block)
  klass = discriminate_class_for_record(attributes)
  instantiate_instance_of(klass, attributes, column_types, &block)
end

На основе словаря атрибутов, instantiate возвращает новый экземпляр соответствующего класса. Принимает только ключи в виде строк.

Например, Post.all может возвращать Комментарии, Сообщения и Электронные письма, храня подкласс записи в атрибуте type. Используя instantiate вместо new, методы поиска гарантируют, что они получают новые экземпляры соответствующего класса для каждой записи.

См. ActiveRecord::Inheritance#discriminate_class_for_record для того, как реализована эта схема наследования «единственной таблицы».

query_constraints(*columns_list) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 488
def query_constraints(*columns_list)
  raise ArgumentError, "You must specify at least one column to be used in querying" if columns_list.empty?

  @query_constraints_list = columns_list.map(&:to_s)
  @has_query_constraints = @query_constraints_list
end

Принимает список имён атрибутов, которые будут использоваться в предложении WHERE запросов SELECT/UPDATE/DELETE и в предложении ORDER BY для методов поиска «#first` и `#last`.

class Developer < ActiveRecord::Base
  query_constraints :company_id, :id
end

developer = Developer.first
# SELECT "developers".* FROM "developers" ORDER BY "developers"."company_id" ASC, "developers"."id" ASC LIMIT 1
developer.inspect # => #<Developer id: 1, company_id: 1, ...>

developer.update!(name: "Nikita")
# UPDATE "developers" SET "name" = 'Nikita' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1

It is possible to update attribute used in the query_by clause:
developer.update!(company_id: 2)
# UPDATE "developers" SET "company_id" = 2 WHERE "developers"."company_id" = 1 AND "developers"."id" = 1

developer.name = "Bob"
developer.save!
# UPDATE "developers" SET "name" = 'Bob' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1

developer.destroy!
# DELETE FROM "developers" WHERE "developers"."company_id" = 1 AND "developers"."id" = 1

developer.delete
# DELETE FROM "developers" WHERE "developers"."company_id" = 1 AND "developers"."id" = 1

developer.reload
# SELECT "developers".* FROM "developers" WHERE "developers"."company_id" = 1 AND "developers"."id" = 1 LIMIT 1
update(id = :all, attributes) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 408
def update(id = :all, attributes)
  if id.is_a?(Array)
    if id.any?(ActiveRecord::Base)
      raise ArgumentError,
        "You are passing an array of ActiveRecord::Base instances to `update`. " \
        "Please pass the ids of the objects by calling `pluck(:id)` or `map(&:id)`."
    end
    id.map { |one_id| find(one_id) }.each_with_index { |object, idx|
      object.update(attributes[idx])
    }
  elsif id == :all
    all.each { |record| record.update(attributes) }
  else
    if ActiveRecord::Base === id
      raise ArgumentError,
        "You are passing an instance of ActiveRecord::Base to `update`. " \
        "Please pass the id of the object by calling `.id`."
    end
    object = find(id)
    object.update(attributes)
    object
  end
end

Обновляет объект (или несколько объектов) и сохраняет его в базе данных, если пройдена валидация. Результирующий объект возвращается независимо от того, был ли успешно сохранён объект в базе данных или нет.

Параметры

  • id — это id или массив id, которые необходимо обновить. Необязательный аргумент, по умолчанию все записи в связи.

  • attributes — это словарь атрибутов или массив словарей.

Примеры

# Updates one record
Person.update(15, user_name: "Samuel", group: "expert")

# Updates multiple records
people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
Person.update(people.keys, people.values)

# Updates multiple records from the result of a relation
people = Person.where(group: "expert")
people.update(group: "masters")

Примечание: обновление большого количества записей выполнит запрос UPDATE для каждой записи, что может привести к проблемам с производительностью. При отсутствии необходимости выполнения обратных вызовов для каждого обновления записи предпочтительнее использовать update_all для обновления всех записей в одном запросе.

update!(id = :all, attributes) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 434
def update!(id = :all, attributes)
  if id.is_a?(Array)
    if id.any?(ActiveRecord::Base)
      raise ArgumentError,
        "You are passing an array of ActiveRecord::Base instances to `update!`. " \
        "Please pass the ids of the objects by calling `pluck(:id)` or `map(&:id)`."
    end
    id.map { |one_id| find(one_id) }.each_with_index { |object, idx|
      object.update!(attributes[idx])
    }
  elsif id == :all
    all.each { |record| record.update!(attributes) }
  else
    if ActiveRecord::Base === id
      raise ArgumentError,
        "You are passing an instance of ActiveRecord::Base to `update!`. " \
        "Please pass the id of the object by calling `.id`."
    end
    object = find(id)
    object.update!(attributes)
    object
  end
end

Обновляет объект (или несколько объектов) так же, как и update, но вызывает update! вместо update, поэтому исключение генерируется, если запись недействительна и сохранение не выполняется.

upsert(attributes, **kwargs) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 252
def upsert(attributes, **kwargs)
  upsert_all([ attributes ], **kwargs)
end

Обновляет или вставляет (upserts) одну запись в базу данных в одном SQL-выражении INSERT. Оно не создаёт экземпляры моделей и не запускает обратные вызовы или валидацию Active Record. Хотя значения, переданные в него, проходят через преобразование типов и сериализацию Active Record.

См. upsert_all для документации.

upsert_all(attributes, on_duplicate: :update, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil) Показать исходный код
# File activerecord/lib/active_record/persistence.rb, line 362
def upsert_all(attributes, on_duplicate: :update, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil)
  InsertAll.new(self, attributes, on_duplicate: on_duplicate, update_only: update_only, returning: returning, unique_by: unique_by, record_timestamps: record_timestamps).execute
end

Обновляет или вставляет (upserts) несколько записей в базу данных в одном SQL-выражении INSERT. Оно не создаёт экземпляры моделей и не запускает обратные вызовы или валидацию Active Record. Хотя значения, переданные в него, проходят через преобразование типов и сериализацию Active Record.

Параметр attributes — это Array словарей. Каждый Hash определяет атрибуты для одной строки и должен иметь одинаковые ключи.

Возвращает ActiveRecord::Result с содержанием, основанным на :returning (см. ниже).

По умолчанию upsert_all будет обновлять все столбцы, которые могут быть обновлены при конфликте. Это все столбцы, кроме первичных ключей, столбцов только для чтения и столбцов, охваченных необязательным unique_by.

Параметры

:returning

(Только PostgreSQL) Массив атрибутов, которые нужно вернуть для всех успешно вставленных записей, по умолчанию — первичный ключ. Передайте returning: %w[ id name ] для id и name или returning: false, чтобы полностью исключить подлежащий RETURNING SQL-оператор.

Вы также можете передать строку SQL, если вам нужен больший контроль над возвращаемыми значениями (например, returning: Arel.sql("id, name as new_name")).

:unique_by

(Только PostgreSQL и SQLite) По умолчанию строки считаются уникальными по каждому уникальному индексу в таблице. Любые дубликаты строк пропускаются.

Чтобы пропустить строки в соответствии с одним уникальным индексом, передайте :unique_by.

Рассмотрим модель Book, где дублирование ISBN не имеет смысла, но если какая-либо строка имеет существующий id или не уникальна по другому уникальному индексу, возникает ActiveRecord::RecordNotUnique.

Уникальные индексы могут быть определены по столбцам или имени:

unique_by: :isbn
unique_by: %i[ author_id name ]
unique_by: :index_books_on_isbn

Поскольку он опирается на информацию об индексе из базы данных, :unique_by рекомендуется использовать в паре с кэшем схемы Active Record.

:on_duplicate

Настройка SQL-предложения обновления, которое будет использоваться в случае конфликта.

ПРИМЕЧАНИЕ: Если вы используете этот параметр, вы должны самостоятельно указать все столбцы, которые хотите обновить.

Пример:

Commodity.upsert_all(
  [
    { id: 2, name: "Copper", price: 4.84 },
    { id: 4, name: "Gold", price: 1380.87 },
    { id: 6, name: "Aluminium", price: 0.35 }
  ],
  on_duplicate: Arel.sql("price = GREATEST(commodities.price, EXCLUDED.price)")
)

См. связанный параметр :update_only. Оба параметра не могут быть использованы одновременно.

:update_only

Укажите список имён столбцов, которые будут обновляться в случае конфликта. Если не указано, upsert_all будет обновлять все столбцы, которые могут быть обновлены. Это все столбцы, кроме первичных ключей, столбцов только для чтения и столбцов, охваченных необязательным unique_by.

Пример:

Commodity.upsert_all(
  [
    { id: 2, name: "Copper", price: 4.84 },
    { id: 4, name: "Gold", price: 1380.87 },
    { id: 6, name: "Aluminium", price: 0.35 }
  ],
  update_only: [:price] # Only prices will be updated
)

См. связанный параметр :on_duplicate . Оба параметра не могут быть использованы одновременно.

:record_timestamps

По умолчанию автоматическое установка значений столбцов со временем управляется конфигурацией модели record_timestamps, соответствующей типичному поведению.

Чтобы переопределить это и принудительно установить столбцы со временем одним или другим способом, передайте :record_timestamps:

record_timestamps: true  # Always set timestamps automatically
record_timestamps: false # Never set timestamps automatically

Примеры

# Inserts multiple records, performing an upsert when records have duplicate ISBNs.
# Here "Eloquent Ruby" overwrites "Rework" because its ISBN is duplicate.

Book.upsert_all([
  { title: "Rework", author: "David", isbn: "1" },
  { title: "Eloquent Ruby", author: "Russ", isbn: "1" }
], unique_by: :isbn)

Book.find_by(isbn: "1").title # => "Eloquent Ruby"

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API