en un objeto ActiveModel, ¿cómo verifico la singularidad?
En la excelente publicación de blog de Bryan Helmkamp llamada "7 patrones para refactorizar los modelos de ActiveRecord de grasa", menciona que usaForm Objects
para abstraer formas multicapa y dejar de usaraccepts_nested_attributes_for
.
Editar: verabajo para una solución.
He duplicado casi exactamente su ejemplo de código, ya que tuve el mismo problema que 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
Una de las cosas diferentes en mi código, es que necesito validar elunicidad del nombre de cuenta (y correo electrónico del usuario). Sin embargo,ActiveModel::Validations
no tiene ununiqueness
validador, ya que se supone que es una variante no respaldada por base de datos deActiveRecord
.
Pensé que hay tres maneras de manejar esto:
Escribe mi propio método para verificar esto (se siente redundante)Incluya ActiveRecord :: Validations :: UniquenessValidator (intente esto, no lo hizo funcionar)O agregue la restricción en la capa de almacenamiento de datosPreferiría usar el último. Pero luego me sigo preguntandocómo Yo implementaría esto.
Yo podria hacer algo como(metaprogramación, necesitaría modificar algunas otras á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
Pero ahora tengo dos cheques corriendo en mi clase, primero usovalid?
y luego uso unrescue
Declaración para las restricciones de almacenamiento de datos.
¿Alguien sabe de una buena manera de manejar este problema? ¿Sería mejor tal vez escribir mi propio validador para esto (pero luego tendría dos consultas a la base de datos, donde idealmente una sería suficiente)?