查看
<%= form_for(@new_credit_entry) do |f| %>
<%= f.date_select :created_on%>
我看到我被允许指定无效日期。这会产生一个params哈希,如下所示
"credit"=>{"created_on(1i)"=>"2013",
"created_on(2i)"=>"2",
"created_on(3i)"=>"31"
这当然是一个不正确的日期。所以我知道我的模型需要对此进行验证 - 可能会使用validates_timeliness gem。我需要知道的是如何在规范中模拟这个
这是一些rails控制台输出
irb(main):056:0> x = Credit.new(created_on: "2013-02-30")
=> #<Credit id: nil, description: nil, credit_category_id: nil, amount: nil, created_on: nil, created_at: nil, updated_at: nil>
irb(main):058:0> x.created_on_before_type_cast
=> "2013-02-30"
irb(main):060:0> x.created_on
=> nil
irb(main):057:0> y = Credit.new(created_on: "2013-03-03")
=> #<Credit id: nil, description: nil, credit_category_id: nil, amount: nil, created_on: "2013-03-03", created_at: nil, updated_at: nil>
irb(main):059:0> y.created_on_before_type_cast
=> "2013-03-03"
irb(main):061:0> y.created_on
=> Sun, 03 Mar 2013
irb(main):062:0> z = Credit.new("created_on(1i)"=>"2013",
irb(main):063:1* "created_on(2i)"=>"2",
irb(main):064:1* "created_on(3i)"=>"31")
=> #<Credit id: nil, description: nil, credit_category_id: nil, amount: nil, created_on: "2013-03-03", created_at: nil, updated_at: nil>
irb(main):065:0> z.created_on
=> Sun, 03 Mar 2013
irb(main):066:0> z.created_on_before_type_cast
=> Sun, 03 Mar 2013
答案 0 :(得分:1)
如果您使用validates_timeliness,则会拒绝您在上面尝试的无效日期。该模型无效,created_on
将为nil
。这包括你提到的日期换行问题。
安装validates_timeliness后,模型中只需要:
validates_date :created_on
这是一个测试各种场景的规范:
describe Credit do
it "rejects single digits" do
credit = Credit.new created_on: "3"
credit.should_not be_valid
credit.created_on.should be_nil
end
it "rejects bad dates" do
credit = Credit.new created_on: "2013-02-31"
credit.should_not be_valid
credit.created_on.should be_nil
end
it "rejects words" do
credit = Credit.new created_on: "some nonsense"
credit.should_not be_valid
credit.created_on.should be_nil
end
it "accepts good dates" do
date = "2013-02-28"
credit = Credit.new created_on: date
credit.should be_valid
credit.created_on.should == Date.parse(date)
end
end
即使没有宝石,你也可以相当轻松地验证这一点,但这看起来像是一个方便的宝石。不要忘记运行发电机来完成安装。
如果您确实选择自行进行验证,则可能会遇到一些问题。
一种情况是,当您尝试将错误值粘贴到date
或datetime
列时,底层数据库的行为会有所不同;有些人在存储的价值和他们自动转换时更灵活。最好提前在Rails方面进行验证。
更大的问题是,在运行验证时,ActiveRecord已经尝试将值转换为与数据库字段类型匹配的类型。如果数据库中date
有created_on
字段,ActiveRecord会将分配给created_on
的每个值转换为Date
对象。对于许多格式错误的日期,这将最终成为nil
。在验证器中,您需要查看created_on_before_type_cast
,它将是原始字符串。 ActiveRecord为每个DB列创建一个动态*_before_type_cast
方法。您可以检查其格式并拒绝错误值。
我提到这些警告鼓励你坚持使用宝石。 :)