Rails Custom Validation Based on a Regex

Rails custom validation based on a regex?

For validation purposes, remember to add the beginning and end of string markers \A and \Z:

validates_format_of :uuid, :with => /\A[A-Za-z\d]([-\w]{,498}[A-Za-z\d])?\Z/i

Otherwise your regex will happily match any string that contains at least a letter or a digit. For some reason Rails implicitly adds the boundaries in the routes. (Probably because it embeds the regex inside a larger one to match the entire URL, with explicit checks for / and the end of the URL.)

Custom validation error message based on regex

You need to place the message key within format otherwise it thinks you're trying to apply a MessageValidator

validates :password, format: { 
with: VALID_PASSWORD_REGEX,
message: 'should contain uppercase, lowercase, number and special character. Between 8 and 15 characters long'
},
allow_nil: true

Rails 4 model custom validation with method - works in console but fails in spec

You use the symbol instead of the variable when checking against the regex or for nil.

unless :bar =~ /^([0-4]{1}\.{1}\d{2})$/  || :bar == nil
errors.add(:bar, "incorrect format")
end

Remove the : from the :bar

* EDIT *

It's not the specs that are failing but the model's validations upon creation. You should use build instead of create

Rails validate two different regex on one model entry

I'll skip ahead and simply say you should skip your custom validator, and just use the format validator with your regexes combined into one:

VALID_TIME_FORMAT_SHORT = /\d{1,2}:\d{2}/  # exactly xx:xx OR x:xx like 25:29, 9:50
VALID_TIME_FORMAT_LONG = /\d{1}:\d{2}:\d{2}/ # exactly x:xx:xx like 1:25:29

VALID_TIME_FORMAT = /\A(#{VALID_TIME_FORMAT_SHORT}|#{VALID_TIME_FORMAT_LONG})\z/

validates :runtime_string, format: { with: VALID_TIME_FORMAT }

You should in any case move your error message into your local file, rather than have English strings embedded in your models.

If you want to salvage your custom validation method, you can't use parenthesis to produce "or" matches in the form x =~ (a || b), that isn't how boolean operators and parenthesis interact. You need x =~ a || x =~ b.

You also appear to be testing the symbol :runtime_string, not the actual value, which is not likely intentional.

How can I store a regex expression string in a helper method to use to validate several different fields?

You can require any file from application.rb:

# application.rb
require Rails.root.join "lib", "regexes.rb"

# lib/regexes.rb
PHONE_NUMBER_REGEX = /your regex/

Then you simply use the constant wherever needed

You can alternatively make use of the built in autoload functionality of Rails, for example with the concern approach the other commenter laid out - the concern file is autoloaded by default, as are models, controllers, etc

Loading custom files instead of using the Rails' defaults might not seem idiomatic or the "rails way". However, I do think it's important to understand that you can load any files you want. Some people autoload the entire lib/ folder and subfolders (see Auto-loading lib files in Rails 4)

Another alternative is to place your code somewhere in the config/initializers folder, these files are automatically loaded at startup and you can define shared classes/modules/constants there

Rails validate format with regex

You need to use anchors \A and \z and modify the pattern to fit that logic as follows:

/\A(\w+(?:[\s-]*\w+)?)(?:,\s*\g<1>)*\z/

See the Rubular demo

Details:

  • \A - start of string
  • (\w+(?:[\s-]*\w+)?) - Group 1 capturing:

    • \w+ - 1 or more word chars
    • (?:[\s-]*\w+)? - 1 or 0 sequences of:

      • [\s-]* - 0+ whitespaces or -
      • \w+ - 1 or more word chars
  • (?:,\s*\g<1>)* - 0 or more sequences of:

    • ,\s* - comma and 0+ whitespaces
    • \g<1> - the same pattern as in Group 1
  • \z - end of string.

How do I validate if my model attribute does NOT match a regex?

What I have understood is that you want the validation to pass if it's not a number so why dont you change the regex to match anything but numbers:

/^(?!\d)/

Using your code it would be

validates_format_of :my_str, :with => /^(?!\d)/, :allow_blank = true

Or:

as the documentation says

Alternatively, you can require that the specified attribute does not
match the regular expression by using the :without option.

So:

validates_format_of :my_str,format: { without => /\d:\d/},  allow_blank = true

with validates_format_of validates the attributes' values by testing whether they match a given regular expression, which is specified using the :with or :without options

How can you specify a custom error message in rails model validation when a regex is not met?

Just add "message" key to your validation hash. Check out the docs.

VALID_NAME_REGEX = /^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/
validates :name, presence: true, format: {
with: VALID_NAME_REGEX,
message: "Name can only include letters, numbers, spaces, underscores, and hyphens"
},
uniqueness: { case_sensitive: false },
length: { minimum: 2, maximum: 20 }


Related Topics



Leave a reply



Submit