Passing a method to validates_format_of - ruby-on-rails

I want to do this:
validates_format_of :email, :with => email_regex
def email_regex
email_name_regex = '[A-Z0-9_\.%\+\-]+'
domain_head_regex = '(?:[A-Z0-9\-]+\.)+'
domain_tld_regex = '(?:[A-Z]{2,4}|museum|travel)'
return /\A#{email_name_regex}##{domain_head_regex}#{domain_tld_regex}\z/i
end
but I am getting an error saying that I have to pass a regex to the validates method. I was sure youo could do something like this.
Am I missing a step?
Thanks

Your code looks OK. And I guess you define email_regex method before it is used by the validates method.
You have to debug what validates_format_of gets (modify RoR code to print the :with argument type). This should be quite easy and help you solve the problem.
Now I can only guess that email_regex method is redefined somewhere and returns something else than Regexp.

What about just using a contstant? This would also ensure that the regexp gets only compiled once.
class ...
FOO_BAR = /#{baz}.../
validatess ... :with => FOO_BAR
but yeah, I'm not sure why your way doesn't work.

Related

Negate regex of validates_format_of

In my rails model I have some kind of template system. I want to make sure that users editing it do not make accidental mistakes so I use some simple validators.
They can use markers like ##user_id## that will be replaced later. I want to make sure they do not enter something like ###user_id## that contains too many #, so not any ### (or ####) must appear in the field.
class Template
validates_format_of :text, :with => /##user_id##/,
:message => "##user_id## must be present"
validates_format_of :text, :not_with => /###/,
:message => "Too many #"
end
Unfortunately there is no :not_with option ... is there any chance to solve it using a :with-regex or should I go a separate validate method?
I tried some negative look-ahead, but as there are (mostly) several ## and only one ### they always match one of them.
Use the :without option:
validates_format_of :text, :without => /###/, :message => "Too many #"
What about this...
validates_format_of :text, :with => /(^|[^#])##user_id##($|[^#])/
EDIT: I copied acheong87's rubular examples with my regex.
Can you do something like this?
/^(.(?!###+user_id##|##user_id###+))*$/
Here's a live demo: http://rubular.com/r/SPwsyDlj0y.
In (more) English, it says,
A string in which no character is followed by ###+user_id## or ##user_id###+.

Specifying two conditions with :if

I have a model which validates presence of an attribute if a check box is checked in the view.
The code is something like this:
validates_presence_of :shipping_first_name, :if => :receive_by_email_is_unchecked
I am looking to have another condition of this validation.So how do I go about doing this ??
My assumption is that something like this would do:
validates_presence_of :shipping_first_name, :if => {:receive_by_email_is_unchecked,:form_first_step_validation}
I am not sure if this is the write way of doing it or not ??
Any suggestions would be appreciated.
You can pass method names in an array:
validates_presence_of :shipping_first_name, :if => [:receive_by_email_is_unchecked, :form_first_step_validation]
Alternatively you can use proc if you don't want to define separate methods just for conditioning validations:
validates_presence_of :shipping_first_name, :if => proc { !receive_by_email? && form_first_step_validation }
I don't think that will work, but have a look at the source code for validates_presence_of https://github.com/rails/rails/blob/master/activemodel/lib/active_model/validations/presence.rb
You can build your own validator to do exactly that
Ryan Bates covered this in one of his first Rails casts
http://railscasts.com/episodes/41-conditional-validations
It's still valid although syntax may be slightly different for Rails v 3 +
I assume you are working on a Rails 2.x app as the syntax you use is not Rails 3 syntax
Rails 3.x syntax would be
validates :field_1, :field_2, :presence_of => true, :if => # Use a proc, or an array of conditions here. see the valid examples and comments that you have already received for this question from #jimworm and #MichaƂ Szajbe

Best rails way to implement custom validations?

I am looking for the best way to implement custom validations. I am aware of this :
validates :email, :uniqueness => {:scope => :user_id}
It works perfect. But, I want to do something like this (fictive case but it illustrates well) :
validates :email, :uniqueness => {:scope => 'user.name'}
I am thinking of using customs validations like explained here on rails cast but it seems a little overkill to use a module for this.
Anyone ?
Use a validation method.
class Model
validate :validate_email_with_scope
private
def validate_email_with_scope
if Model.where(...).any?
errors.add(:email, 'is not unique')
end
end
end
Replace Model.where(...).any? with your query.

Rails - Regex inside a method used for validations

I have a validation that checks the format of a url using regex. I was wondering if it's possible to put the regex inside of a method:
validates_format_of :table_name :with => /^(http|https):\/\/[a-z0-9]+([_-.]{1}[a-z0-9]+).[a-z]{2,5}(:[0-9]{1,5})?(\/.)?$/ix
How do I put that regex in a method and use it with the validation?
If you wish to tidy up code without creating a custom validation, then use a constant rather than a method to store the regex.
class Product < ActiveRecord::Base
URL_REGEX = /^(http|https):\/\/[a-z0-9]+([\_\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
validates_format_of :table_name :with => URL_REGEX
end
It'll work with any class method, or variable/constant that's already defined. But why don't you create a new validator?
# config/initializers/my_validators.rb
ActiveRecord::Base.class_eval do
def self.validates_url_of(attr_name, n, options={})
validates_format_of attr_name, :with => /^(http|https):\/\/[a-z0-9]+([_-.]{1}[a-z0-9]+).[a-z]{2,5}(:[0-9]{1,5})?(\/.)?$/ix
end
end
Then:
class Foo < ActiveRecord::Base
validates_url_of :attribute
end
See http://guides.rubyonrails.org/active_record_validations_callbacks.html#creating-custom-validation-methods
I recommend you take a look at Ruby - Validate and update URL for a much better validation method than regex.
If you're desperate to use Regex, then take a look at this writeup from John Gruber for something much more valuable than the above.

validation of special characters

i want to put validation in ruby on rails that my username should not contain special characters like !##$%^*()_-+=/<>?:'";.
Please tell me how can i implement it in my code.
Using your model validates_format_of as suggested by #Voyta
I am adding a regular expression in my example though :
validates_format_of :username, :with => /\A[a-zA-Z]+([a-zA-Z]|\d)*\Z/
Use validates_format_of (see comments there for regex examples):
validates_format_of :username, :with => /\Ayour_regex_here\Z/i

Resources