I want to active record validate for big integer max value 9223372036854775807
but it can't validate
validates_numericality_of :amount, presence: true, :length => 4, :allow_blank => false, :only_integer => true, :greater_than => 0, :less_than_or_equal_to => 9223372036854775807
What does it mean, it doesn't validate?
Do you have any stacktrace?
You usually want to validate the value on creation, hence your code could look like this:
validates_numericality_of :amount, on: :create, presence: true, length: 4, allow_blank: false, only_integer: true, greater_than: 0, less_than_or_equal_to: 9223372036854775807
Related
if I do
validates :body, :presence => true, :length => {:maximum => 30000, :message => ' is a bit long...'}
validates :body, :length => {:minimum => 10, :message => ' is a bit short...'}
I still have a possibility of having a text which includes only spaces and /r or /n - non visible chars, which while the text isn't blank by definition, it is blank by looking at it
How can I validate that the text had a min and max length listed above and is also visible (not 10 spaces)
Rails adds the handy method blank? which checks for false, nil and empty strings as described here.
Rails also adds the handy validator allow_blank: false.
So in your case it should be:
validates :body, presence: true, allow_blank: false
Edit (original answer above):
As stated in the answer below, allow_blank: false is not needed as that's the default behaviour of presence: true.
presence: true already does that according to
http://guides.rubyonrails.org/active_record_validations.html#presence
This helper validates that the specified attributes are not empty. It uses the blank? method to check if the value is either nil or a blank string, that is, a string that is either empty or consists of whitespace.
What if you try adding something like this:
validates_format_of :body, :with => /\A[[:graph:]]\Z/i
Notes:
validates_format_of lets you validate with regex
[[:graph:]] lets you check a string for printable characters (see "Character Classes")
This is my model:
class User < ActiveRecord::Base
attr_accessible :email, :name
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: true
end
The author of Rails Tutorial Example said "Curly braces are optional when passing hashes as the final argument in a method", but here the presence validation is not final argument, but it can be used without curly braces and is valid code. The format validation of email attribute also works.
Anybody can explain me why?
:name, :presence: true, length: { maximum: 50 } is the last argument passed to validates, so you don't need curly braces for it.
A case where you would need curly braces would be if you were passing arguments after that hash:
validates { :name, presence: true, length: { maximum: 50 } }, some_other_argument
Where some_other_argument here is some hypothetical argument that comes after the hash. To process this correctly you would need the curly braces around the hash.
I have an invoice model with approver_note, po_number and state_id.
I need validations to check:
validates :approver_note, :presence => true, {:scope => state_id == 3}
validates :po_number, :presence => true, {:scope => state_id ==2}
So, if the user selects state_id = 3, he must enter a note.
If he selects state_id = 2, he must enter a po_number.
Any assistance would be great... thanks!
You're looking for the :if option instead of :scope.
validates :approver_note, :presence => true,
:if => lambda { |invoice| invoice.state_id == 3 }
But since a lambda is a little ugly, I'd probably add a method to encapsulate what you're doing a bit better:
validates :approver_note, :presence => true, :if => :requires_note?
validates :po_number, :presence => true, :if => requires_po_number?
def requires_note?
state_id == 3
end
def requires_po_number?
state_id == 2
end
If you actually have a bunch of different attributes that are required when state_id is 3, not just a note, then you may want something like this:
validates :approver_note, :presence => true, :if => :green_state?
validates :po_number, :presence => true, :if => orange_state?
def green_state?
state_id == 3
end
def orange_state?
state_id == 2
end
(Replace "green" with -- I dunno -- "high_documentation" or whatever makes sense in your world.)
Or maybe you want to let the state decide what it is:
def green_state?
state.green?
end
It really does help to make the terminology in your code adhere more closely to your real-world language, as opposed to "3" and "2".
I am implementing a validation scheme and am using the bcrypt-ruby gem.
require 'bcrypt'
class User < ActiveRecord::Base
include BCrypt
attr_accessor :password
attr_accessible :name, :email, :password, :password_confirmation
validates :password, :presence => true, :on => :create,
:confirmation => true,
:length => {:within => 6..12}
before_save :encrypt_password
def has_password?(submitted_password)
self.encrypted_password == submitted_password # this calls a method in bcrypt
# File lib/bcrypt.rb, line 171
# def ==(secret)
# super(BCrypt::Engine.hash_secret(secret, #salt))
# end
end
private
def encrypt_password
self.encrypted_password = Password.create(password, :cost => 5)
end
end
Now in the console I create a new user
>> user = User.create!(:name => "test", :email => "test#test.com", :password => "foobar", :password_confirmation => "foobar")
=> #<User id: 1, name: "test", email: "test#test.com", created_at: "2011-06-23 05:00:00", updated_at: "2011-06-23 05:00:00", encrypted_password: "$2a$10$I7Wy8NDMeVcNgOsE3J/ZyubiNAESyxA7Z49H4p1x5xxH...">
And if I check if the password is valid I do the following:
>> user.has_password?("foobar")
=> true
but if I get the user from the database it fails:
user = User.find(1)
user.has_password?("foobar")
=> false
Why does that happen and how can I implement bcrypt to make this work?
Thank you in advance.
My guess would be that since encrypted_password is stored in the database as a string and not a BCrypt::Password, you're not calling into BCrypt's ==, but rather String's ==. You have to instantiate an instance of the Password around the string hash value. That would be where I'd look.
As described over here you have to use the password class of Bcrypt to utilize the ==
def has_password?(submitted_password)
Bcrypt::Password.new(self.encrypted_password) == submitted_password
end
This seems like a simple question but I can't seem to find an answer short of writing custom validators. I have this validator
validates :password, :presence => true, :confirmation => true, :length => { :minimum => 5}
there are more rules applied such as some regex for complexity, but this gives the gist.
The issue is that I only want presence applied on create, everything else needs to be on create and update. Because the user may not be changing a password when updating their information.
I tried splitting the rules
validates :password, :presence => true, :on => :create
validates :password, # The rest of the rules
This resulted in all rules being ignored for update. Is there a simple way to apply only one rule to create and the rest to everything?
You can try keeping it in one line, but applying :on => :create to just the :presence check:
validates :password, :presence => {:on => :create}, :confirmation => true, :length => { :minimum => 5}
However, I'm not sure it makes sense to always require a minimum length, but not always require presence -- if you update an existing record with a blank password, it's going to fail validations anyway since the length is 0.
My hunch is that the problem is that the validate :password call is not additive. Can you switch the presence check to:
validates_presence_of :password, :on=>:create
And then keep your other validations using the validate. Does that work?