How to write validation in rails so as to allow the below possible values for price
100 or $100 or 100.00 or $100.00
I have declared price field as Float in my model
My current code looks like :
validates :price,numericality: true
which is not allowing values like 100 to get saved.
You can add the format option to your validates method.
validates :price, numericality: true,
:format => { :with => /^\d{1,6}(\.\d{0,2})?$/
This will allow values of up to $999999.99 with an optional decimal place (if the decimal is present, no more than 2 digits must follow.)
But like others already mentioned - it's not the best option to save these values into the database.
I can recommend you the RubyMoney gem for working with currencies.
Related
I have a pieces model in my rails app, and each piece has a decimal called :price. I want to validate that this price is two decimal places, greater than 0, and is less than a million dollars. I have looked at numerous sources on Stack overflow, and whenever I type a decimal for these validations, for example, 4.99 , the price becomes 4.990000000000000213162820728030055761. This has happened for all the validations I have looked up. Is this because I need to specify my precision for the decimal in my database? How can I fix this?
My current validation:
validates :price, :presence => true, :format => { :with => /\A(\$)?(\d+)(\.|,)?\d{0,2}?\z/ }
Thanks guys!
I dont know which database you are using but you can define precision in your migration like this,
add_column :pieces, :price, :decimal, precision: 8, scale: 2
It will give you a total of 8 digits, with 2 after the decimal point.
About the validation,
If you want that the :price should always have two decimal place (i.e: 4.99) you can try this,
validates :price, presence: true, format: { with: /\A\d+(?:\.\d{2})?\z/ }, numericality: { greater_than: 0, less_than: 1000000 }
If you want that the :price should have at most two decimal or less (i.e: 4, 4.9, 4.99) you can try this,
validates :price, presence: true, format: { with: /\A\d+(?:\.\d{0,2})?\z/ }, numericality: { greater_than: 0, less_than: 1000000 }
Or if you dont want to validate precision and just want to round up the precision before you save it to the database you can use round_with_precision.
You should set it on the database. For example in a migration:
add_column :products, :price, :decimal, precision: 5, scale: 2
Precision is the number of digits in a number. Scale is the number of
digits to the right of the decimal point in a number. For example, the
number 123.45 has a precision of 5 and a scale of 2. In SQL Server,
the default maximum precision of numeric and decimal data types is 38.
https://msdn.microsoft.com/en-us/library/ms190476.aspx
If you're seeing that your values are having additional numbers tacked on, what's likely happening is that your column is set as a floating-point type. If you're working with dollar values do not use floating-point numbers. M. Karim's answer is fine otherwise.
I want to write a validation for ensuring the minimum and maximum value of an integer column.
I know I can use the helpers of the numericality validation as follow:
validates :column_name, numericality: {
only_integer: true,
greater_than: 0,
less_than: 100
}
My question however, is that if I want to give a database level validation for this, how can I go about it
PS: I'm using Postgres.
You can use a domain; something like:
CREATE DOMAIN something AS INT CHECK (VALUE BETWEEN 1 AND 99)
and then declare the table column as the type something.
In Rails 4, how can you add a model validation for a maximum value on an integer column?
For example, I want to add a validation to the column "age", to have a maximum value of 100.
There are many questions with answers for Rails 3 and earlier. The docs do not mention any way of checking integer values.
Take a look at the numericality validators.
In your case, something like
validates :age, numericality: { less_than_or_equal_to: 100, only_integer: true }
How do I specify a limit on an integer size in a Rails 4 migration? (My database is PostgreSQL.)
I have fields for phone_number, which should be 8 digits long. If I specify :limit => 8, then that is byte size rather than the length of the numbers.
Is there a way to do this?
You're going about this all wrong. A phone number is not a number at all, a phone number is a string that contains (mostly) digit characters. You don't do anything numeric – such as arithmetic – with phone numbers so they're not numbers, they're strings.
Make your phone_number column a string of length eight:
t.string :phone_number, limit: 8
and clean it up and validate the format in your model:
before_validation :clean_up_phone_number
validates :phone_number,
format: { with: /\A\d{8}\z/ },
length: { maximum: 8 },
allow_nil: true
def clean_up_phone_number
# Do whatever you want or need to strip out spaces, hyphens, etc. in here
end
Or better with PostgreSQL, don't worry about the size in the database at all and use t.string :phone_number. The size limit just adds pointless overhead and using a plain varchar rather than a varchar(8) makes it easier to allow for different phone number formats (area codes, extensions, international numbers, ...) later.
Or you can do it with mv-core gem (https://github.com/vprokopchuk256/mv-core) right in a migration in this way (syntax is almost identical to AciveModel::Validations one):
def change
update_table :users do |table|
t.string :phone_number,
validates: { length: 8,
format: /\A\d{8}\z/,
allow_blank: true,
allow_nil: true }
end
end
And then bubble up that validation to your model:
class User < ActiveRecord::Base
enforce_migration_validations
end
By default your validation will be defined as CHECK constraint for PostgreSQL. But you can change that to trigger constraint, for ex.
See details in the documentation.
I have a string column in a table that can have a range of predefined values. It can also include a nil value. For ex: Dog, Cat, Bird, nil.
I want to write a validates_inclusion_of that checks to make sure all the values being entered fall within that predefined range. If, for ex, "Nasal Spray" is entered, it will throw an error.
What's the best way to do so?
Use the following validation within your model class:
validates_inclusion_of :animal, :in => %w(Dog Cat Bird), :allow_blank => true
—where :animal is the name of the column you want to validate.