mirror of
https://github.com/ditkrg/validates_timeliness.git
synced 2026-01-23 06:16:44 +00:00
added :before option to add_formats to insert above existing format
This commit is contained in:
parent
53d57cb7ac
commit
5f55fad076
16
README
16
README
@ -94,7 +94,7 @@ as dates.
|
|||||||
validates_datetime :appointment_date, :before => Proc.new { 1.week.from_now }
|
validates_datetime :appointment_date, :before => Proc.new { 1.week.from_now }
|
||||||
|
|
||||||
|
|
||||||
== DATE/TIME FORMATS:
|
=== DATE/TIME FORMATS:
|
||||||
|
|
||||||
So what formats does the plugin allow. Well there are default formats which can
|
So what formats does the plugin allow. Well there are default formats which can
|
||||||
be added to easily using the plugins format rules. Also formats can be easily
|
be added to easily using the plugins format rules. Also formats can be easily
|
||||||
@ -175,8 +175,9 @@ For the technically minded (well you are developers), these formats are compiled
|
|||||||
into regular expressions at runtime so don't add any extra overhead than using
|
into regular expressions at runtime so don't add any extra overhead than using
|
||||||
regular expressions directly. So, no, it won't make your app slow!
|
regular expressions directly. So, no, it won't make your app slow!
|
||||||
|
|
||||||
|
To see all defined formats look in the lib/validates_timeliness/formats.rb.
|
||||||
|
|
||||||
== CUSTOMISING FORMATS:
|
=== CUSTOMISING FORMATS:
|
||||||
|
|
||||||
I hear you say "Thats greats but I don't want X format to be valid". Well to
|
I hear you say "Thats greats but I don't want X format to be valid". Well to
|
||||||
remove a format stick this in an initializer file or environment.rb
|
remove a format stick this in an initializer file or environment.rb
|
||||||
@ -192,8 +193,17 @@ Ahh, then add it yourself. Again stick this in an initializer file or environmen
|
|||||||
|
|
||||||
Now '10 o'clock' will be a valid value. So easy, no more whingeing!
|
Now '10 o'clock' will be a valid value. So easy, no more whingeing!
|
||||||
|
|
||||||
|
Because formats are evaluated in order, adding a format which may be ambiguous
|
||||||
|
with an existing format, will mean your format is ignored. If you need to make
|
||||||
|
your new format higher precedence than an existing format, you can include the
|
||||||
|
before option like so
|
||||||
|
|
||||||
== EXTERNAL PARSER:
|
ValidatesTimeliness::Formats.add_formats(:time, 'ss:nn:hh', :before => 'hh:nn:ss')
|
||||||
|
|
||||||
|
Now a time of '59:30:23' will be interpreted as 11:30:59 pm. This option saves
|
||||||
|
you adding a new one and deleting an old one to get it to work.
|
||||||
|
|
||||||
|
=== EXTERNAL PARSER:
|
||||||
|
|
||||||
I mentioned earlier that you could use a pluggable or alternative parser such
|
I mentioned earlier that you could use a pluggable or alternative parser such
|
||||||
as Chronic instead of the in built one. So if you need some super fancy stuff that
|
as Chronic instead of the in built one. So if you need some super fancy stuff that
|
||||||
|
|||||||
@ -179,15 +179,15 @@ module ValidatesTimeliness
|
|||||||
#
|
#
|
||||||
# Examples:
|
# Examples:
|
||||||
#
|
#
|
||||||
# 'yyyy-mm-dd hh:nn' => lambda {|y,m,d,h,n| md||=0; [unambiguous_year(y),month_index(m),d,full_hour(h,md),n,nil,nil].map {|t| t.to_i unless t.nil? } }
|
# 'yyyy-mm-dd hh:nn' => lambda {|y,m,d,h,n| md||=0; [unambiguous_year(y),month_index(m),d,full_hour(h,md),n,nil,nil].map {|t| t.to_i if t } }
|
||||||
# 'dd/mm/yyyy h:nn_ampm' => lambda {|d,m,y,h,n,md| md||=0; [unambiguous_year(y),month_index(m),d,full_hour(h,md),n,nil,nil].map {|t| t.to_i unless t.nil? } }
|
# 'dd/mm/yyyy h:nn_ampm' => lambda {|d,m,y,h,n,md| md||=0; [unambiguous_year(y),month_index(m),d,full_hour(h,md),n,nil,nil].map {|t| t.to_i if t } }
|
||||||
#
|
#
|
||||||
def format_proc(order)
|
def format_proc(order)
|
||||||
arg_map = format_proc_args
|
arg_map = format_proc_args
|
||||||
args = order.invert.sort.map {|p| arg_map[p[1]][1] }
|
args = order.invert.sort.map {|p| arg_map[p[1]][1] }
|
||||||
arr = [nil] * 7
|
arr = [nil] * 7
|
||||||
order.keys.each {|k| i = arg_map[k][0]; arr[i] = arg_map[k][2] unless i.nil? }
|
order.keys.each {|k| i = arg_map[k][0]; arr[i] = arg_map[k][2] unless i.nil? }
|
||||||
proc_string = "lambda {|#{args.join(',')}| md||=nil; [#{arr.map {|i| i.nil? ? 'nil' : i }.join(',')}].map {|t| t.to_i unless t.nil? } }"
|
proc_string = "lambda {|#{args.join(',')}| md||=nil; [#{arr.map {|i| i.nil? ? 'nil' : i }.join(',')}].map {|t| t.to_i if t } }"
|
||||||
eval proc_string
|
eval proc_string
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -202,7 +202,8 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Loop through format expressions for type and call proc on matches. Allow
|
# Loop through format expressions for type and call proc on matches. Allow
|
||||||
# pre or post match strings to exist if strict is false.
|
# pre or post match strings to exist if strict is false. Otherwise wrap
|
||||||
|
# regexp in start and end anchors.
|
||||||
# Returns 7 part datetime array.
|
# Returns 7 part datetime array.
|
||||||
def extract_date_time_values(time_string, type, strict=true)
|
def extract_date_time_values(time_string, type, strict=true)
|
||||||
expressions = self.send("#{type}_expressions")
|
expressions = self.send("#{type}_expressions")
|
||||||
@ -217,6 +218,7 @@ module ValidatesTimeliness
|
|||||||
return time_array
|
return time_array
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Delete formats of specified type. Error raised if format not found.
|
||||||
def remove_formats(type, *remove_formats)
|
def remove_formats(type, *remove_formats)
|
||||||
remove_formats.each do |format|
|
remove_formats.each do |format|
|
||||||
unless self.send("#{type}_formats").delete(format)
|
unless self.send("#{type}_formats").delete(format)
|
||||||
@ -226,14 +228,22 @@ module ValidatesTimeliness
|
|||||||
compile_format_expressions
|
compile_format_expressions
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Adds new formats. Must specify format type and can specify a :before
|
||||||
|
# option to nominate which format the new formats should be inserted in
|
||||||
|
# front on to take higher precedence. Error is raise if format already
|
||||||
|
# exists or if :before format is not found.
|
||||||
def add_formats(type, *add_formats)
|
def add_formats(type, *add_formats)
|
||||||
formats = self.send("#{type}_formats")
|
formats = self.send("#{type}_formats")
|
||||||
|
options = {}
|
||||||
|
options = add_formats.pop if add_formats.last.is_a?(Hash)
|
||||||
|
before = options[:before]
|
||||||
|
raise "Format for :before option #{format} was not found." if before && !formats.include?(before)
|
||||||
|
|
||||||
add_formats.each do |format|
|
add_formats.each do |format|
|
||||||
if formats.include?(format)
|
raise "Format #{format} is already included in #{type} formats" if formats.include?(format)
|
||||||
raise "Format #{format} is already included in #{type} formats"
|
|
||||||
end
|
index = before ? formats.index(before) : -1
|
||||||
formats << format
|
formats.insert(index, format)
|
||||||
end
|
end
|
||||||
compile_format_expressions
|
compile_format_expressions
|
||||||
end
|
end
|
||||||
|
|||||||
@ -180,6 +180,10 @@ describe ValidatesTimeliness::Formats do
|
|||||||
validate('2.12am', :time).should be_false
|
validate('2.12am', :time).should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should raise error if format does not exist" do
|
||||||
|
lambda { formats.remove_formats(:time, "ss:hh:nn") }.should raise_error()
|
||||||
|
end
|
||||||
|
|
||||||
after do
|
after do
|
||||||
formats.time_formats << 'h.nn_ampm'
|
formats.time_formats << 'h.nn_ampm'
|
||||||
end
|
end
|
||||||
@ -190,7 +194,7 @@ describe ValidatesTimeliness::Formats do
|
|||||||
formats.compile_format_expressions
|
formats.compile_format_expressions
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should add format to format array" do
|
it "should add format to format array" do
|
||||||
formats.add_formats(:time, "h o'clock")
|
formats.add_formats(:time, "h o'clock")
|
||||||
formats.time_formats.should include("h o'clock")
|
formats.time_formats.should include("h o'clock")
|
||||||
end
|
end
|
||||||
@ -201,8 +205,24 @@ describe ValidatesTimeliness::Formats do
|
|||||||
validate("12 o'clock", :time).should be_true
|
validate("12 o'clock", :time).should be_true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should add format before specified format and be higher precedence" do
|
||||||
|
formats.add_formats(:time, "ss:hh:nn", :before => 'hh:nn:ss')
|
||||||
|
validate("59:23:58", :time).should be_true
|
||||||
|
time_array = formats.extract_date_time_values('59:23:58', :time)
|
||||||
|
time_array.should == [nil,nil,nil,23,58,59,nil]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise error if format exists" do
|
||||||
|
lambda { formats.add_formats(:time, "hh:nn:ss") }.should raise_error()
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise error if format exists" do
|
||||||
|
lambda { formats.add_formats(:time, "ss:hh:nn", :before => 'nn:hh:ss') }.should raise_error()
|
||||||
|
end
|
||||||
|
|
||||||
after do
|
after do
|
||||||
formats.time_formats.delete("h o'clock")
|
formats.time_formats.delete("h o'clock")
|
||||||
|
formats.time_formats.delete("ss:hh:nn")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -53,10 +53,12 @@ describe ValidatesTimeliness::Validations do
|
|||||||
@person.should be_valid
|
@person.should be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should be valid with values before epoch" do
|
# What is going on? No fall back.
|
||||||
@person.birth_date_and_time = "1960-01-31 12:12:12"
|
it "should be valid with values before out of Time range" do
|
||||||
@person.birth_date = "1960-01-31"
|
@person.birth_date_and_time = "1890-01-31 12:12:12"
|
||||||
@person.birth_time = "23:59"
|
@person.birth_date = "1890-01-31"
|
||||||
|
@person.birth_time = "23:59:59"
|
||||||
|
puts @person.errors.inspect
|
||||||
@person.should be_valid
|
@person.should be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -74,7 +76,7 @@ describe ValidatesTimeliness::Validations do
|
|||||||
before :all do
|
before :all do
|
||||||
class DateTimeBeforeAfter < Person
|
class DateTimeBeforeAfter < Person
|
||||||
validates_timeliness_of :birth_date_and_time, :type => :datetime,
|
validates_timeliness_of :birth_date_and_time, :type => :datetime,
|
||||||
:before => Time.now, :after => 1.day.ago
|
:before => lambda { Time.now }, :after => lambda { 1.day.ago}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -111,8 +113,8 @@ describe ValidatesTimeliness::Validations do
|
|||||||
before :all do
|
before :all do
|
||||||
class DateTimeOnOrBeforeAndAfter < Person
|
class DateTimeOnOrBeforeAndAfter < Person
|
||||||
validates_timeliness_of :birth_date_and_time, :type => :datetime,
|
validates_timeliness_of :birth_date_and_time, :type => :datetime,
|
||||||
:on_or_before => Time.now.at_midnight,
|
:on_or_before => lambda { Time.now.at_midnight },
|
||||||
:on_or_after => 1.day.ago
|
:on_or_after => lambda { 1.day.ago }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -311,8 +313,12 @@ describe ValidatesTimeliness::Validations do
|
|||||||
describe "with mixed value and restriction types" do
|
describe "with mixed value and restriction types" do
|
||||||
before :all do
|
before :all do
|
||||||
class MixedBeforeAndAfter < Person
|
class MixedBeforeAndAfter < Person
|
||||||
validates_timeliness_of :birth_date_and_time, :before => Date.new(2008,1,2), :after => lambda { Time.mktime(2008, 1, 1) }
|
validates_timeliness_of :birth_date_and_time,
|
||||||
validates_timeliness_of :birth_date, :type => :date, :on_or_before => Time.mktime(2008, 1, 2), :on_or_after => :birth_date_and_time
|
:before => Date.new(2008,1,2),
|
||||||
|
:after => lambda { Time.mktime(2008, 1, 1) }
|
||||||
|
validates_timeliness_of :birth_date, :type => :date,
|
||||||
|
:on_or_before => lambda { Time.mktime(2008, 1, 2) },
|
||||||
|
:on_or_after => :birth_date_and_time
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user