神刀安全网

Rails 5 adds a way to get information about types of failed validations

May 03, 2016 – Abhishek Jain

This blog is part of ourRails 5 series.

Let’s look at a validation example in Rails 4.x.

class User < ActiveRecord::Base   validates :email, presence: true end  >> user = User.new >> user.valid? => false  >> user.errors.messages => {:email=>["can't be blank"]}

In this case, we do not get any information about the type of failed validation as ActiveModel#Errors only gives the attribute name and the translated error message.

This works out well for normal apps. But in case of API only applications, sometimes we want to allow the client consuming the API to generate customized error message as per their needs. We don’t want to send the final translated messages in such cases. Instead if we could just send details that presence validation failed for :name attribute, the client app would be able to customize the error message based on that information.

In Rails 5, it is now possible to get such details about which validations failed for a given attribute.

We can check this by calling details method on the ActiveModel#Errors instance.

class User < ApplicationRecord   validates :email, presence: true end  >> user = User.new >> user.valid? => false  >> user.errors.details => {:email=>[{:error=>:blank}]}

We can also add custom validator types as per our need.

# Custom validator type >> user = User.new >> user.errors.add(:name, :not_valid, message: "The name appears invalid")  >> user.errors.details => {:name=>[{:error=>:not_valid}]}  # Custom error with default validator type :invalid  >> user = User.new >> user.errors.add(:name)  >> user.errors.details => {:name=>[{:error=>:invalid}]}  # More than one error on one attribute  >> user = User.new >> user.errors.add(:password, :invalid_format, message: "Password must start with an alphabet") >> user.errors.add(:password, :invalid_length, message: "Password must have atleast 8 characters")  >> user.errors.details => {:password=>[{:error=>:invalid_format}, {:error=>:invalid_length}]}

Passing contextual information about the errors

We can also send contextual data for the validation to the Errors#add method. This data can be later accessed via Errors#details method because Errors#add method forwards all options except :message , :if , :unless , and :on to details .

For eg. we can say that the password is invalid because ! is not allowed, as follows.

class User < ApplicationRecord   validate :password_cannot_have_invalid_character    def password_cannot_have_invalid_character     if password.scan("!").present?       errors.add(:password, :invalid_character, not_allowed: "!")     end   end end  >> user = User.create(name: 'Mark', password: 'Ra!ls') >> user.errors.details => {:password=>[{:error=>:invalid_character, :not_allowed=>"!"}]}

We can also use this feature in our Rails 4.x apps by simply installing gem active_model-errors_details .

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Rails 5 adds a way to get information about types of failed validations

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址