0

意見

<%= 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を使用します。私が知る必要があるのは、仕様でこれをシミュレートする方法です

ここにいくつかのレールコンソール出力があります

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
4

1 に答える 1

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

これは、gem がなくてもかなり簡単に検証できる可能性がありますが、使用するのに便利な gem のように見えます。ジェネレーターを実行してインストールを完了することを忘れないでください。

独自の検証をロールすることを選択した場合、いくつかの問題が発生する可能性があります。

date1 つは、またはdatetime列に不適切な値を挿入しようとすると、基になるデータベースの動作が多少異なることです。保存する値と実行する自動変換においてより柔軟なものもあります。事前に Rails 側で検証することをお勧めします。

より大きな問題は、検証が実行されるまでに、ActiveRecord がすでに値をデータベース フィールド タイプと一致するタイプにキャストしようとしていることです。dateデータベースに のフィールドがある場合created_on、ActiveRecord は に割り当てられたすべての値をオブジェクトに変換created_onDateます。それはnil多くの不正な日付になるでしょう。created_on_before_type_castバリデーターでは、生の文字列であるを見たいと思うでしょう。ActiveRecord は、*_before_type_castすべての DB 列に対して動的メソッドを作成します。その形式を確認して、不適切な値を拒否できます。

gem を使い続けるように促すために、これらの注意事項について言及します。:)

于 2013-03-17T07:58:51.620 に答える