tag rails form different collection and ruby-on-rails validation rails-activerecord

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