на объекте ActiveModel, как проверить уникальность?

В отличном посте Брайана Хелмкампа под названием "7 шаблонов для рефакторинга жирных моделей ActiveRecord«Он упоминает, используяForm Objects абстрагировать многослойные формы и прекратить использованиеaccepts_nested_attributes_for.

Изменить: см.ниже для решения.

Я почти точно продублировал его пример кода, так как мне пришлось решить ту же проблему:

class Signup
  include Virtus

  extend ActiveModel::Naming
  include ActiveModel::Conversion
  include ActiveModel::Validations

  attr_reader :user
  attr_reader :account

  attribute :name, String
  attribute :account_name, String
  attribute :email, String

  validates :email, presence: true
  validates :account_name,
    uniqueness: { case_sensitive: false },
    length: 3..40,
    format: { with: /^([a-z0-9\-]+)$/i }

  # Forms are never themselves persisted
  def persisted?
    false
  end

  def save
    if valid?
      persist!
      true
    else
      false
    end
  end

private

  def persist!
    @account = Account.create!(name: account_name)
    @user = @account.users.create!(name: name, email: email)
  end
end

Одна из особенностей моего кода состоит в том, что мне нужно проверитьуникальность имени учетной записи (и электронной почты пользователя). Тем не мение,ActiveModel::Validations не имеетuniqueness валидатор, так как он должен быть вариантом базы данных без базы данныхActiveRecord.

Я подумал, что есть три способа справиться с этим:

Напишите мой собственный метод, чтобы проверить это (чувствует себя излишним)Включить ActiveRecord :: Validations :: UniquenessValidator (пробовал, не получалось)Или добавьте ограничение в слой хранения данных

Я бы предпочел использовать последний. Но потом я продолжаю задаваться вопросомкак Я бы это реализовал.

Я мог бы сделать что-то вроде(метапрограммирование, мне нужно будет изменить некоторые другие области):

  def persist!
    @account = Account.create!(name: account_name)
    @user = @account.users.create!(name: name, email: email)
  rescue ActiveRecord::RecordNotUnique
    errors.add(:name, "not unique" )
    false
  end

Но теперь у меня есть две проверки в моем классе, сначала я используюvalid? а потом я используюrescue оператор для ограничений хранения данных.

Кто-нибудь знает хороший способ справиться с этой проблемой? Было бы лучше, возможно, написать свой собственный валидатор для этого (но тогда у меня будет два запроса к базе данных, где в идеале будет достаточно одного).

Ответы на вопрос(2)

Ваш ответ на вопрос