ruby on rails - form - Rails ActiveRecord: valida un solo atributo
ruby and rails documentation (3)
A veces hay validaciones que son bastante costosas (por ejemplo, validaciones que necesitan realizar consultas en la base de datos). En ese caso, debe evitar el uso de valid?
porque simplemente hace mucho más de lo que necesitas.
Hay una solución alternativa. Puede usar el método validators_on
de ActiveModel::Validations
.
validators_on (* attributes) public
Enumere todos los validadores que se utilizan para validar un atributo específico.
según el cual puedes validar manualmente los atributos que deseas
por ejemplo, solo queremos validar el title
de la Post
:
class Post < ActiveRecord::Base
validates :body, caps_off: true
validates :body, no_swearing: true
validates :body, spell_check_ok: true
validates presence_of: :title
validates length_of: :title, minimum: 30
end
Donde no_swearing
y spell_check_ok
son métodos complejos que son extremadamente caros.
Podemos hacer lo siguiente:
def validate_title(a_title)
Post.validators_on(:title).each do |validator|
validator.validate_each(self, :title, a_title)
end
end
que validará solo el atributo de título sin invocar ninguna otra validación.
p = Post.new
p.validate_title("")
p.errors.messages
#=> {:title => ["title can not be empty"]
Nota
No estoy completamente seguro de que se supone que debemos usar validators_on
manera segura, por lo que consideraría manejar una excepción de una manera validates_title
en validates_title
.
Si hay una manera en que puedo validar un solo atributo en Rails?
Algo como:
ac_object.valid?(attribute_name)
Voy a usarlo para la validación de AJAX de campos de modelos particulares. Mover estas validaciones al Javascript hace que el código sea realmente feo.
Puede implementar su propio método en su modelo. Algo como esto
def valid_attribute?(attribute_name)
self.valid?
self.errors[attribute_name].blank?
end
O agréguelo a ActiveRecord::Base
Terminé basándose en la respuesta de @ xlembouras y agregué este método a mi ApplicationRecord
:
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
def valid_attributes?(*attributes)
attributes.each do |attribute|
self.class.validators_on(attribute).each do |validator|
validator.validate_each(self, attribute, send(attribute))
end
end
errors.none?
end
end
Entonces puedo hacer cosas como esta en un controlador:
if @post.valid_attributes?(:title, :date)
render :post_preview
else
render :new
end