Ответ 1
Вы можете реализовать свой собственный метод в своей модели. Что-то вроде этого
def valid_attribute?(attribute_name)
self.valid?
self.errors[attribute_name].blank?
end
Или добавьте его в ActiveRecord::Base
Если есть способ, я могу проверить один атрибут в Rails?
Что-то вроде:
ac_object.valid?(attribute_name)
Я буду использовать его для проверки AJAX определенных полей модели. Перемещение этих валидаций в Javascript делает код действительно уродливым.
Вы можете реализовать свой собственный метод в своей модели. Что-то вроде этого
def valid_attribute?(attribute_name)
self.valid?
self.errors[attribute_name].blank?
end
Или добавьте его в ActiveRecord::Base
Иногда есть довольно дорогостоящие проверки (например, проверки, которые должны выполнять запросы к базе данных). В этом случае вам нужно избегать использования valid?
, потому что это просто намного больше, чем вам нужно.
Существует альтернативное решение. Вы можете использовать validators_on
метод ActiveModel::Validations
.
validators_on (* attributes) public
Перечислите все валидаторы, которые используются для проверки определенного атрибут.
в соответствии с которым вы можете вручную подтвердить наличие необходимых атрибутов
например. мы хотим только проверить title
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
Где no_swearing
и spell_check_ok
- сложные методы, которые чрезвычайно дороги.
Мы можем сделать следующее:
def validate_title(a_title)
Post.validators_on(:title).each do |validator|
validator.validate_each(self, :title, a_title)
end
end
который будет проверять только атрибут title, не вызывая никаких других проверок.
p = Post.new
p.validate_title("")
p.errors.messages
#=> {:title => ["title can not be empty"]
Я не уверен, что мы должны использовать validators_on
безопасно, поэтому я бы рассмотрел возможность обработки исключения разумным способом в validates_title
.
Я закончил работу над ответом @xlembouras и добавил этот метод к моему 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
Тогда я могу делать такие вещи в контроллере:
if @post.valid_attributes?(:title, :date)
render :post_preview
else
render :new
end
Мне нравится решение @coreyward и внес некоторые изменения. Вот что я использую:
приложение/модель/проблемы/attribute_validator.rb
module AttributeValidator
extend ActiveSupport::Concern
def attributes_valid?(*attribute_names)
attribute_names.each do |attribute|
self.class.validators_on(attribute).each do |validator|
validator.validate_each(self, attribute, send(attribute))
end
errors.slice(*attributes).none?
end
end
end
Использование:
приложение/модели/user.rb
include AttributeValidator
def something
do_something if attributes_valid?(:email)
end