I am new at Ruby on Rails.
I was trying to validate format of one of the attribute to enter only float.
validates :price, :format => { :with => /^[0-9]{1,5}((\.[0-9]{1,5})?)$/, :message => "should be float" }
but when I enter only character in price, it accepts it and show 0.0 value for price.
can anybody tell, what is wrong in this or why this happens?
This is my solution,
validates :price,presence:true, numericality: {only_float: true}
when you fill in for example 7 it automatically transfer the value to 7.0
For rails 3:
validates :price, :format => { :with => /^\d+??(?:\.\d{0,2})?$/ },
:numericality =>{:greater_than => 0}
A float is a number and regular expressions are for strings.
It appears that when you enter a string for the float, it gets converted as 0.0 automatically by Rails.
Do you have a default (0.0) on the column? If yes, then you may try removing it and use validates_presence_of :price only.
Something to try: instead of putting the string directly into the price column, put it into a price_string attr and use a before_save callback to try to convert the string to price. Something like that:
attr_accessor :price_string
before_save :convert_price_string
protected
def convert_price_string
if price_string
begin
self.price = Kernel.Float(price_string)
rescue ArgumentError, TypeError
errors.add(ActiveRecord::Errors.default_error_messages[:not_a_number])
end
end
And in your form, change the name of the text_field to :price_string.
Related
I have an input (it's text input) where users can set up the price.
The problem is, that users can sometimes set up the price like this:
9
9.99
9,99
$9.99
What's the best way to validate this input? I am running the app on Heroku (= PostgreSQL database), the data type column is decimal.
Rails 4 complains about using $ and ^, so use:
validates :price, :presence => true,
:format => { :with => /\A(\$)?(\d+)(\.|,)?\d{0,2}?\z/ }
Just trying to save people time ;-)
Try something like below. It matches all you examples.
validates :price, :presence => true,
:format => { :with => /^(\$)?(\d+)(\.|,)?\d{0,2}?$/ }
Hi I have a model called users, and they have a cell phone attribute that must be entered as a 12 digit string leading with "+". I want to validate that the attribute they entered from a form is in fact in the correct format. Example "+11234567890" should save to the model, but "1232h" will not.
This is what I have in my model, but it does not work:
validates :cell, :format => { :with => /^[-+]?[0-9]+$/,
:message => "Only numbers allowed" }, :length => { :is => 10 }
Try this:
validates :cell, :format => { :with => /\A(\+1)?[0-9]{10}\z/, :message => "Not a valid 10-digit telephone number" }
I think the problem is that you're trying to do two different kinds of validations on a single validates line. The above combines the length constraint with the number constraint, and allows the variable +/- without messing up the length constraint.
I'm using a regex to validate a form field in my sinatra app that's being sent to my db using the data_mapper gem. The code I'm using for the field in my model is:
property :price, Float, :required => true, :format => /\$?\d{0,3}\.{1}\d{2}/
And it's being saved from the params:
b.price = params[:price]
I keep getting an invalid format error when I try to save, though. I checked my regex with rubular and it seems to be working correctly. Anyone have any idea what's going wrong?
It's not perfect, but here's what I'm currently doing as a solution:
property :price, Float, :required => true
validates_format_of :price, :with => /\$?\d{0,3}(\.{1}\d{2})?/
And then:
c = params[:price]
c[0] == "$" ? b.price = c[1,7] : b.price = c
So if there's a "$" I'm just saving the number to b.price without it, otherwise the whole thing gets set to b.price. I feel like there should be a better way...
What is the best/easy way to validate an email address in ruby (on the server side)?
You could look whether or not it matches a regexp like the one used in this Rails validator:
validates_format_of :email,:with => /\A[^#\s]+#([^#\s]+\.)+[^#\s]+\z/
But if you use Devise, simply do:
validates_format_of :email,:with => Devise::email_regexp
Source: http://lindsaar.net/2008/4/14/tip-4-detecting-a-valid-email-address
Edit 1:
useful website for tests: http://www.rubular.com/
In Ruby? The same way as in any language.
Send a confirmation email to the address with a link that the recipient has to click before the email address is considered fully validated.
There are any number of reasons why a perfectly formatted address may still be invalid (no actual user at that address, blocked by spam filters, and so on). The only way to know for sure is a successfully completed end-to-end transaction of some description.
validates :email, presence: true, format: /\w+#\w+\.{1}[a-zA-Z]{2,}/
checks that email field is not blank and that one or more characters are both preceding the '#' and following it
Added specificity, any 1 or more word characters before an the #and any 1 or more word character after and in between specifically 1 . and at least 2 letters after
I know that this is a old question but I was looking for a simple to way to do this. I came across a email_validator gem this is really simple to set up and use.
as a validator
validates :my_email_attribute, :email => true
Validation outside a model
EmailValidator.valid?('narf#example.com') # boolean
I hope that this help everyone.
Happy Codding
Shortcut Form:
validates :email, :format => /#/
Normal Form (Regex) :
validates :email, :format => { :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }
Source: Validator Class
You can use
<%=email_field_tag 'to[]','' ,:placeholder=>"Type an email address",:pattern=>"^([\w+-.%]+#[\w-.]+\.[A-Za-z]{2,4},*[\W]*)+$",:multiple => true%>
Since the main answer's blog site was down, here is the snippet of code from that site via nice cacher or gist:
# http://my.rails-royce.org/2010/07/21/email-validation-in-ruby-on-rails-without-regexp/
class EmailValidator < ActiveModel::EachValidator
# Domain must be present and have two or more parts.
def validate_each(record, attribute, value)
address = Mail::Address.new value
record.errors[attribute] << (options[:message] || 'is invalid') unless (address.address == value && address.domain && address.__send__(:tree).domain.dot_atom_text.elements.size > 1 rescue false)
end
end
You can take reference from https://apidock.com/rails/ActiveModel/Validations/HelperMethods/validates_format_of
validates_format_of :email, with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
If you are using Rails/Devise - addition to #apneadiving`s answer -
validates_format_of :email,:with => Devise::email_regexp
Devise::email_regexp is taken from config/initializers/devise.rb
config.email_regexp = /\A[^#\s]+#([^#\s]+\.)+[^#\s]+\z/
Send a confirmation mail , and I will usualy use this validator ... D.R.Y.
# lib/email_validator.rb
class EmailValidator < ActiveModel::EachValidator
EmailAddress = begin
qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-' +
'\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
quoted_pair = '\\x5c[\\x00-\\x7f]'
domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d"
quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22"
domain_ref = atom
sub_domain = "(?:#{domain_ref}|#{domain_literal})"
word = "(?:#{atom}|#{quoted_string})"
domain = "#{sub_domain}(?:\\x2e#{sub_domain})*"
local_part = "#{word}(?:\\x2e#{word})*"
addr_spec = "#{local_part}\\x40#{domain}"
pattern = /\A#{addr_spec}\z/
end
def validate_each(record, attribute, value)
unless value =~ EmailAddress
record.errors[attribute] << (options[:message] || "is not valid")
end
end
end
in your model
validates :email , :email => true
or
validates :email, :presence => true,
:length => {:minimum => 3, :maximum => 254},
:uniqueness => true,
:email => true
I have a Phone model for phone numbers in my application thats built as follows:
t.column :number, :string
t.references :phoneable, :polymorphic => true
I want to restrict the number to be of the format 317.555.5555x234, so I'm creating a form with four boxes (area code, 3 digits, 4 digits, ext):
- form_for #user do |user_form|
-user_form.fields_for :phones do |phone|
= phone.text_field :area_code
= phone.text_field :first_three_digits
etc...
I'm assuming a virtual attribute would be the route to go (a la railscasts ep16), but not sure how to assemble the "number" from the 4 separate text_fields.
I think I would have to do something like this:
def full_number=(phone)
self.number = area_code+"."+first_three_digits+"."+second_four_digits+"."+extension
end
But I'm unsure of how to approach this in assembling the number from form inputs. Any thoughts?
I normally do this as a before_save:
before_save :update_phone_number
def update_phone_number
self.phone_number = [area_code, first_three_digits, second_four_digits, extension].reject(&:blank?).join('.')
end
First I would have some validations:
validates_presence_of :area_code, :first_three_digits, :second_four_digits
validates_format_of :area_code, :with => /\d{3}/
validates_format_of :first_three_digits, :with => /\d{3}/
validates_format_of :second_four_digits, :with => /\d{4}/
validates_format_of :extension, :with => /\d{0,6}/, :allow_blank => true
This is just to make sure that you get valid data in your phone number and your before save doesn't throw any errors. I also assumed that you would allow the extension to be blank, but is easily changed.
EDIT: you will want to have attr_accessors for the different segments of the phone number:
attr_accessor :area_code, :first_three_digits, :second_four_digits, :extension