em um objeto ActiveModel, como faço para verificar a exclusividade?

No excelente post do blog de Bryan Helmkamp chamado "7 padrões para refatorar modelos ActiveRecord Fat", ele menciona usandoForm Objects para abstrair formas de múltiplas camadas e parar de usaraccepts_nested_attributes_for.

Editar: vejaabaixo para uma solução.

Eu praticamente dupliquei a amostra de código dele, pois tive o mesmo problema a resolver:

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

Uma das coisas diferentes no meu pedaço de código, é que eu preciso validar osingularidade do nome da conta (e e-mail do usuário). Contudo,ActiveModel::Validations não tem umuniqueness validador, como é suposto ser uma variante deActiveRecord.

Eu percebi que existem três maneiras de lidar com isso:

Escreva meu próprio método para verificar isso (parece redundante)Incluir ActiveRecord :: Validações :: UniquenessValidator (tentei isto, não funcionou)Ou adicione a restrição na camada de armazenamento de dados

Eu preferiria usar o último. Mas então eu fiquei me perguntandocomo Eu implementaria isso.

Eu poderia fazer algo parecido(metaprogramação, eu precisaria modificar algumas outras áreas):

  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

Mas agora eu tenho duas verificações em execução na minha turma, primeiro eu usovalid? e então eu uso umrescue declaração para as restrições de armazenamento de dados.

Alguém sabe de uma boa maneira de lidar com esse problema? Seria melhor talvez escrever meu próprio validador para isso (mas então eu teria duas consultas ao banco de dados, onde, idealmente, uma seria suficiente).

questionAnswers(2)

yourAnswerToTheQuestion