[ACCEPTED]-Rails ActiveRecord: validate single attribute-rails-activerecord
You can implement your own method in your 1 model. Something like this
def valid_attribute?(attribute_name)
self.valid?
self.errors[attribute_name].blank?
end
Or add it to ActiveRecord::Base
Sometimes there are validations that are 17 quite expensive (e.g. validations that need 16 to perform database queries). In that case 15 you need to avoid using valid?
because it simply 14 does a lot more than you need.
There is an 13 alternative solution. You can use the validators_on
method 12 of ActiveModel::Validations
.
validators_on(*attributes) public
List 11 all validators that are being used to validate 10 a specific attribute.
according to which 9 you can manually validate for the attributes 8 you want
e.g. we only want to validate the 7 title
of 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
Where no_swearing
and spell_check_ok
are complex methods that 6 are extremely expensive.
We can do the following:
def validate_title(a_title)
Post.validators_on(:title).each do |validator|
validator.validate_each(self, :title, a_title)
end
end
which 5 will validate only the title attribute without 4 invoking any other validations.
p = Post.new
p.validate_title("")
p.errors.messages
#=> {:title => ["title can not be empty"]
note
I am not 3 completely confident that we are supposed 2 to use validators_on
safely so I would consider handling 1 an exception in a sane way in validates_title
.
I wound up building on @xlembouras's answer 2 and added this method to my 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
Then I can 1 do stuff like this in a controller:
if @post.valid_attributes?(:title, :date)
render :post_preview
else
render :new
end
Building on @coreyward's answer, I also 1 added a validate_attributes!
method:
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
def validate_attributes!(*attributes)
valid_attributes?(*attributes) || raise(ActiveModel::ValidationError.new(self))
end
end
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.