2010-12-03 23 views
11

日付Railsは時間と私は以下の備品を持っていた備品

Links.where("Date(created_at) = ?", 5.day.ago.to_date) 

回答:

[] 

grrrr .. ..タイピング...タイピング...スクラッチ... 私は最終的に試してみました:

link_1: 
    user: tom 
    image: boy1 
    created_at: <%= 5.day.ago.to_date %> 

Links.where("Date(created_at) = ?", 5.day.ago.to_date) 

は最終的に私は期待していたが、なぜ私はTO_DATEを配置する必要がありました何

[#<Link id: 298486374, user_id: 1038054164, image_id: 482586125, created_at: "2010-11-28 00:00:00", updated_at: "2010-12-03 21:32:19">] 

に答えますか?

Links.where("Date(created_at) = ?", Date.today) 

任意のアイデア:私は作成日付を指定せずにオブジェクトを作成するとき、私は問題なく、次のwhere句でそれらを選択することができますので、私には明確ではないでしょうか?

+0

私はより明確になります。私の質問は次のとおりです。.to_dateを私はそれを置いていないときではない。 – standup75

答えて

1

私は、フィクスチャが作成されたときとクエリが呼び出されたときの時間差のためだと推測します。

5日前5日前

+ 0.00025ミリ>私は精度が日付時刻何のためにあるのかわからないんだけど、それは私が考えることができる唯一の可能性です。日付に変換すると、余分な時間情報が削除され、2つのデータが均等にレンダリングされます。

+0

最後の例のLinks.where( "Date(created_at)=?"、Date.today)が正常に動作して以来、これはタイムゾーンの問題ではありません – standup75

+0

タイムゾーンの問題ではありません。比較する時(12/05/2010 12:00:00.0005)と比較して、日時がフィクスチャとして挿入されるまでの間にわずかな遅延があります(12/05/2010 12:00:00.0000と言います)。それは私が話していた時差です。 –

0

to_dateを呼び出すと、時間の値が失われるため、最終結果はcreated_atタイムスタンプがその日の深夜に設定されていることが原因です。また、タイムゾーン変換をTimeWithZoneから避けてください。率直に言えば、これを超えて起こっていることを推測するのに十分な情報がありません。何が起きているのかを正確に確認するには、log/test.logのクエリを確認することです。クエリが表示されない場合はlog_level:debugに設定してconfig/environments/test.rbに設定することができます。ここでSQLクエリをコピーして貼り付けてください。

@Ibzでも良い点があります:.to_s(:db)を使用すると、フィクスチャファイルERBが文字列に評価され、YAMLとして読み込まれるため、文字列に値をキャストする際に問題が発生する可能性があります。 .to_s(:db)を使用するとこの問題は修正されますが、将来この問題を回避するには(追加の機能がたくさんあります)、フィクスチャの代わりにfactory_girlを使用することをおすすめします。

これらの種類の問題は、テストの日付を処理する場合によく発生します。特に、2つの日付またはタイムスタンプの等価性によってクエリを実行しようとしている場合は、これらの問題に取り組むには、5.days.agoの代わりに過去の任意の固定日付/時刻を選択するか、動的な日付/時刻を使用する必要がある場合は、Timecop gemを使用してテスト内の時間を制御/固定します。備品で

+0

私の質問はなぜ「それは働いていないのですか」よりもなぜ働いたのですか? – standup75

+0

@ standup75:回答が編集されました。 – wuputah

19

あなたが持っている必要があります。

created_at: <%= 5.day.ago.to_s(:db) %> 

あなたのクエリは次のようになります。

Links.where("created_at = ?", ... 

はActiveRecordのから、データベースにデータを移動するの詳細の世話をしてみましょう。私たちは理由のためにORMを使用しています。

Reference

+0

to_s(:db)はここに行く方法ですが、私はこれを自分で実行しました。 –

+0

5.day.ago == 5.day.ago.to_date =>私には間違いはありますが、ここでは問題ではありません。私のポイントは、私が.to_dateを置いたときに働いていたことです。 – standup75

+0

5.day.ago( 'ActiveSupport :: TimeWithZone'型)を' Date'に変換します。データベースに保存されているものは、後で 'Date(created_at)= ...'というクエリで 'Date'にキャストされます。 'Date'はあなたのRailsアプリケーションの時間やタイムゾーンを気にしません。 'rails console'を起動して、 '5.day.ago.go'、' 5.day.ago.to_date'、 '5.day.ago.to_s(:db) 'と入力した結果を見比べるで。異なる_values_が表示されます。 – lbz

1

created_atはDateTimeフィールドであり、5.days.agoは実質的にDateTimeオブジェクトを返します。このオブジェクトは、呼び出されたときと同じ時刻に設定されます。土、2014年8月23日10:30:これはデータベースに格納されます。

エラーが発生した場合、5.days.agoを(同じ実行であっても)もう一度呼び出すと、新しい時刻が異なる可能性があります。土、2014年8月23日10:30:したがって、あなたは彼らが平等ではないことが分かり、あなたはマッチを得ることはありません。

.to_dateを追加すると、時間コンポーネントを持たないDateオブジェクトが取得されます。これがデータベースに永続化されるか、クエリで使用されると、常に00:00:00(深夜)の時間があるとみなされます。したがって、日付と時刻は一致します(昼食を実行して真夜中に正確にクエリを実行しない限り)

関連する問題