QA@IT

datetime_selectでdiscard_minuteすると、空欄編集でエラー

2890 PV

以下の環境、手順で操作すると、エラーになってしまいます。。

Ruby 1.9.3
Rails 2.3.18
PostgreSQL 9.3

手順

  • end_at というカラムに対して、viewでdatetime_select を使います。
    年月日時まで設定したいので、「分」を使わないよう、discard_minute: true を付けます。

    <%= f.datetime_select :end_at, discard_minute: true, :start_year => Date.today.year, :include_blank => true %>
    
  • 必須項目ではないため、model側ではvalidates_presence_ofなどは設定していません。

  • 必須項目ではないため、:include_blank => true を付けます。

このような状況で最初は値を入れて登録し、:include_blank => true にしているので空欄で更新すると、以下のエラーが出ます。

PG::Error: ERROR:  date/time field value out of range: "0000-01-01 00:00:00.000000"

クエリのパラメタを見ると、次のようになっていて、分にあたるend_at(5i)に0が設定されています。

 "end_at(1i)"=>"", "end_at(2i)"=>"", "end_at(3i)"=>"", "end_at(4i)"=>"", "end_at(5i)"=>"0"}

結果、0000-01-01 00:00:00.000000 とDB側で認識され、out of range エラーになっているのでは、と思います。

discart_minuteを付けなければ、空欄で更新してもエラーにはなりませんでした。
しかし、分はつけたくない要件があり、一からエラーを回避するプログラムを組むしか無いのか、
または何かスマートな解決策があるのか、悩んでおります。

どなたか解決策をご存知の方いらっしゃりましたら、アドバイスいただけると幸いです。

よろしくお願いいたします。

回答

一度 end_at に値を入れると、datetime_select で生成される <input type="hidden"> の値が 0 になるため、質問の状態になってしまうようですね。

datetime_select の実装をいじるのは面倒なので、モデルに渡す前に end_at(5) を削除してしまうのが手軽かと思います。

params["foo"].delete("end_at(5i)")
p params["foo"] #=> {"end_at(1i)"=>"", "end_at(2i)"=>"", "end_at(3i)"=>"", "end_at(4i)"=>""}
編集 履歴 (0)
  • ご回答ありがとうございます!
    また、ご連絡が遅くなって失礼いたしました。

    ご指摘いただいた通り、パラメタから「秒」にあたる "end_at(5i)" を削除することでうまくNULL更新できることが確認できました。

    アドバイス、誠にありがとうございました。

    ※あとは、どこに書くか。。controllerか、modelか。。うーん。
    -

間違えて自分の質問にthanksコメントしてしまったので、削除しました。

編集 履歴 (1)
ウォッチ

この質問への回答やコメントをメールでお知らせします。