I am trying to validate the entry a user makes in an amount field.
The field is amount_money
This field is a string which is validated on form submission
monetize :amount, :as => :amount_money
validates :amount, numericality: {only_integer: true}
validates :amount_money, numericality: {greater_than_or_equal_to: 0}
validate :amount_money_within_limit
validate :is_a_valid_number
I want to ensure there are no letters or symbols and that the amount is in an acceptable range.
the code to do this is
def amount_money_within_limit
if amount_money && amount_money.cents > 10_000_00
errors.add(:amount_money, 'cannot exceed $10,000.')
end
if amount_money && amount_money.cents < 1_00
errors.add(:amount_money, 'Problem with Amount')
end
end
this works great for input numbers, of numbers and letters, of letters, of special characters but
If I try Bob - the validation kicks in
but if I try BBob - the validation is bypassed.
If the input contains 2 Capital letters next to each other - it fails.
I've tried a downcase - but that doesn't suit as the field is monetized (money gem) - and the downcase screws up if there is valid input.
If the input to the field contains two uppercase letters - all the validations are bypassed So something like AA is not caught by any on the above validations
Why don't you use regular expressions? Something like this:
def is_a_valid_number? amount_money
amount_money =~ /\d+/
end
It seems you have put 1 validation on the wrong field, you should've put validations only on amount field (your real db field), and not on the amount_money which is automagical field from rails-money gem. I'll apply their documentation on numerical validations to your case:
monetize :amount,
:numericality => {
:only_integer => true,
:greater_than_or_equal_to => 1_00,
:less_than_or_equal_to => 10_000_00
}
You won't need any other custom validations with this setup.
Related
I have a model with fields that are validated frontend with client side validations gem.
My problem is for the below field (European VAT number for France) :
validates :VAT, length: { maximum: 15 }
validates :VAT, format: { with: /\A[a-zA-Z]{2}\d{0,13}\z/ }
Also I have this callback in order to normalize it before validation :
before_validation :normalize_vat
def normalize_vat
if self.VAT.present?
self.VAT[0]=self.VAT[0].capitalize
self.VAT[1]=self.VAT[1].capitalize
self.VAT = self.VAT.delete(' ')
end
end
This callback capitalize letters and strips the spaces that a user could have input such as :
FR 333 3333 333333
Though it seems client_side_validations is not picking the callback frontend...
I could change the regexp to match any spaced input but it wrecks a bit my validations as I can't validate length no more for example ...
Would there be a trick to fix this ?
I havel a model with validators on some fields. Example:
class Notation < ActiveRecord::Base
validates :name, presence: true, uniqueness: true
validates_length_of :name, minimum: 5, maximum: 128
end
is there a way to get those values from minimum and maximum for the :name field in the template (because I want to show there the value of min and max length to the user, and want to do this dynamically, with the template reflecting the values from the model)?
In the rails console, I can do something like
Notation.validators_on(:name)
which outputs
#<ActiveRecord::Validations::PresenceValidator:0x00000005428420 #attributes=[:name], #options={}>, #<ActiveRecord::Validations::UniquenessValidator:0x0000000541b8d8 #attributes=[:name], #options={:case_sensitive=>true}, #klass=Notation (call 'Notation.connection' to establish a connection)>, #<ActiveModel::Validations::LengthValidator:0x0000000540baf0 #attributes=[:name], #options={:minimum=>5, :maximum=>128}>
If I get using the array's index
Notation.validators_on(:name)[2]
I have:
#<ActiveModel::Validations::LengthValidator:0x0000000540baf0 #attributes=[:name], #options={:minimum=>5, :maximum=>128}>
but I was wondering if there is another way, maybe passing the type of validation I'm 'queryng', because I can't rely on the order of the array.
To get the validator, you can filter:
options = Notation.validators_on(:name)
.select { |v| v.is_a? LengthValidator }
.first.options
Then you can get options[:maximum] etc.
In case there is no such validator, you might have to rescue from the code, as otherwise the first will fail.
I'm trying to validate the format of a field in an ActiveRecord. I want this field to either be empty, or contain a sequence of digits only (it is containing an optional port number for a database connection). I'm currently trying this:
validates_format_of :port, with: /\A[0-9]*\Z/, message: 'Only numbers allowed'
but without luck. I've found that adding a required number by using for example {1, 6} sort of works, but makes the field mandatory.
Any advice?
Many thanks in advance,
Joseph.
If you're looking to validate so that only numbers are allowed, then you should be able to use this:
validates :port, :numericality => {:only_integer => true}
You may want to try to validate the numericality of the field, like so:
validates_numericality_of :port, :only_integer => true
:only_integer will ensure that the value entered for :port is an integer.
You can also just add allow_blank: true
You can use this syntax as well
validates numericality: :only_integer
I want to use the validates method on one of my text fields in a model so that the end user must enter at least 25 lines (separated with an enter key). So for now i validate the presence of the input so it won't be blank:
validates :lines, :presence => true
This must use some regex to check for maybe the presence of at least 24 '\n' ?
How can i accomplish that in my model?
EDIT: values need to be utf8
Maybe you have to do it with validate method:
validate do
errors.add(:lines, "must be at least 25 lines") if lines.lines.to_a.size < 25
end
If you really need to do it with regexp, try something like
/([^\n]*\n[^\n]*){24,}/
but it counts empty lines as well.
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.