Ruby on Rails
Wednesday, February 1, 2012
On Wed, Feb 1, 2012 at 10:24 AM, sandip ransing <sandip@funonrails.com> wrote:
OK, get it. I continue below.
With setting an error then:
u = User.new
u.birth_date = '31/31/2011'
u.birth_date #=> nil
u.valid? #=> true
u.birth_date = '1/1/2011'
u.birth_date #=> Sat, 01 Jan 2011
UNTESTED:
ONLY WORKs in Rails 3.2.x
birth_date = is overriden and call the original birth_date = with a properly parsed Date object
my_parsed_date will set an error if the parsing failed,
so you object is not longer valid.
NOT TESTED, but indicative of a style.
class User
def birth_date=(bd)
super(my_parsed_date(bd, :birth_date))
end
end
# this function could go in a library somewhere
def my_parsed_date(bd, attr)
begin
Date.strptime(bd, "%m/%d/%Y")
rescue ArgumentError
self.errors.add(attr, "date is invalid")
nil # this will be returned upon rescue
end
end
HTH,
Peter
-- Hi Peter,
validating date against Date.strptime('DATE STRING') will surely work.
At controller level, i can able to do validation on date but at model level it goes for toss bcz value gets nil before validation(at assignment level)
Would you please go through my previous reply.
OK, get it. I continue below.
On Wed, Feb 1, 2012 at 2:43 PM, Peter Vandenabeele <peter@vandenabeele.com> wrote:
On Wed, Feb 1, 2012 at 9:22 AM, sandip ransing <sandip@funonrails.com> wrote:
consider scenario,
User model with name, birth_date fields
(here birth_date is not mandatory field)inside view form birth_date is assigned as '31/31/1985' which is invalid
ideally user object should be invalid and while save raise an error on birth_date field but that's not happening and user object gets saved with birth_date as blank which is completely misleading.
You are probably tripped up by the same unexpected behavior I recently discovered.
At least with Postgresql, if you assign a completely invalid string to a date (or a datetime)
field, it does not throw an exception but simply sets the value to nil:
> c.birth_date = "2012-01-15"
=> "2012-01-15"
1.9.3-p0 :011 > c.save!
(0.2ms) BEGIN
(0.4ms) UPDATE "children" SET "birth_date" = '2012-01-15', "updated_at" = '2012-02-01 08:52:13.063755' WHERE "children"."id" = 1
(8.5ms) COMMIT
=> true
1.9.3-p0 :012 > c.birth_date = "2012-01-45"
=> "2012-01-45"
1.9.3-p0 :013 > c.save!
(0.2ms) BEGIN
(0.4ms) UPDATE "children" SET "birth_date" = NULL, "updated_at" = '2012-02-01 08:54:46.965404' WHERE "children"."id" = 1
(18.8ms) COMMIT
=> true
I would have expected an exception here as the POLS.
But on 'true' it does raise an exception (I discovered this
because Rails.logger.warning now returns true).
c.birth_date = true
=> true
1.9.3-p0 :015 > c.save!
(0.2ms) BEGIN
(0.4ms) UPDATE "children" SET "birth_date" = 't', "updated_at" = '2012-02-01 08:56:00.771141' WHERE "children"."id" = 1
PGError: ERROR: invalid input syntax for type date: "t"
LINE 1: UPDATE "children" SET "birth_date" = 't', "updated_at" = '20...
^
: UPDATE "children" SET "birth_date" = 't', "updated_at" = '2012-02-01 08:56:00.771141' WHERE "children"."id" = 1
(0.2ms) ROLLBACK
ActiveRecord::StatementInvalid: PGError: ERROR: invalid input syntax for type date: "t"
After debugging found that while assigning attributes birth_date value it gets assigned as blank and as birth_date is optional object gets saved.
class User < ActiveRecord::Base
Any clue how to get validation working properly for not mandatory date fields ??
def initialize(args={})
logger.info args[:birth_date] #invalid value comes upto here but vanishes afterwords
super
end
end
As for the validation. You could use a regex, as suggested by Neethu, but that has the limitation
that it is hard do calculate that 2012-01-29 is OK en 2013-01-29 is not OK.
Better may be to use a combination of strptime and rescue ArgumentError
1.9.3-p0 :051 > begin
1.9.3-p0 :052 > Date.strptime("29/02/2012", "%d/%m/%Y")
1.9.3-p0 :053?> rescue ArgumentError
1.9.3-p0 :054?> puts "This date is invalid"
1.9.3-p0 :055?> end
=> Wed, 29 Feb 2012
1.9.3-p0 :056 > begin
1.9.3-p0 :057 > Date.strptime("2012-31-31", "%Y-%m-%d")
1.9.3-p0 :058?> rescue ArgumentError
1.9.3-p0 :059?> puts "This date is invalid"
1.9.3-p0 :060?> end
This date is invalid
=> nil #This comes from the last line in the rescue block, which is puts here
1.9.3-p0 :061 > begin
1.9.3-p0 :062 > Date.strptime("10/01/2012", "%d/%m/%Y")
1.9.3-p0 :063?> rescue ArgumentError
1.9.3-p0 :064?> puts "This date is invalid"
1.9.3-p0 :065?> end
=> Tue, 10 Jan 2012 # Correct EU dd/mm/yyyy intepretation
1.9.3-p0 :066 > begin
1.9.3-p0 :067 > Date.strptime("10/01/2012", "%m/%d/%Y")
1.9.3-p0 :068?> rescue ArgumentError
1.9.3-p0 :069?> puts "This date is invalid"
1.9.3-p0 :070?> end
=> Mon, 01 Oct 2012 # Correct US mm/dd/yyyy interpretation
With setting an error then:
u = User.new
u.birth_date = '31/31/2011'
u.birth_date #=> nil
u.valid? #=> true
u.birth_date = '1/1/2011'
u.birth_date #=> Sat, 01 Jan 2011
UNTESTED:
ONLY WORKs in Rails 3.2.x
birth_date = is overriden and call the original birth_date = with a properly parsed Date object
my_parsed_date will set an error if the parsing failed,
so you object is not longer valid.
NOT TESTED, but indicative of a style.
class User
def birth_date=(bd)
super(my_parsed_date(bd, :birth_date))
end
end
# this function could go in a library somewhere
def my_parsed_date(bd, attr)
begin
Date.strptime(bd, "%m/%d/%Y")
rescue ArgumentError
self.errors.add(attr, "date is invalid")
nil # this will be returned upon rescue
end
end
HTH,
Peter
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment