Rails 3の検索で、日付の比較よりも優れた方法はありますか?


125

私はRails 3でこの検索を行っています。

Note.where(:user_id => current_user.id, :notetype => p[:note_type], :date => p[:date]).order('date ASC, created_at ASC')

しかし、私は:date => p[:date]条件が平等である必要があります:date > p[:date]。これどうやってするの?読んでくれてありがとう。

回答:


226
Note.
  where(:user_id => current_user.id, :notetype => p[:note_type]).
  where("date > ?", p[:date]).
  order('date ASC, created_at ASC')

または、すべてをSQL表記に変換することもできます

Note.
  where("user_id = ? AND notetype = ? AND date > ?", current_user.id, p[:note_type], p[:date]).
  order('date ASC, created_at ASC')

2
安全ですか?つまり、p [:date]がユーザー入力から来た場合、SQLインジェクションを引き起こす可能性がありますか?
MhdSyrwan 2012

7
ので安全ですwhere()。を使用where()すると、入力が自動的にエスケープされます。
Simone Carletti、2012

34
Simoneのコメントは完全に真実ではありません。where()変数の代わりに疑問符を付けて上記の形式で使用すると、入力は自動的にエスケープされ、後で関数呼び出しにリストされます。このようにそれを使用しても安全ではない:Note.where("date > #{p[:date]}")
BDX

4
また、注目に値するのは、両方にフィールドがあるモデルをマージする場合where("user_id = ?",current_user.id)よりも使用する方がリスクが高いwhere(user_id: current_user.id)ことですuser_id。生のSQL表記を使用する場合は、テーブルの説明を自分で含める必要がありますwhere("notes.user_id = ?",current_user.id)
DreadPirateShawn 2014

1
タイムゾーンのため、これには注意が必要です。「」のある場所を使用すると、Railsはデータベースに直接移動し、データベースには日付がUTCで保存されますが、たとえばUTC + 5である必要があり、これは正しくありません。そのため、実行する前にp [日付]を現在のUTCに変換してください
Paulo Tarud

70

列名があいまいである問題に遭遇した場合、次のことができます。

date_field = Note.arel_table[:date]
Note.where(user_id: current_user.id, notetype: p[:note_type]).
     where(date_field.gt(p[:date])).
     order(date_field.asc(), Note.arel_table[:created_at].asc())

2
何らかの理由で、PostgreSQLサーバーでSimoneの「where」メソッドを使用しても列が見つからないというエラーが発生しましたが、SQLiteでは機能しました。あなたの方法は両方でうまくいきました。
plackemacher

2

あなたが使用しようとすることができます:

where(date: p[:date]..Float::INFINITY)

SQLで同等

WHERE (`date` >= p[:date])

結果は次のとおりです。

Note.where(user_id: current_user.id, notetype: p[:note_type], date: p[:date]..Float::INFINITY).order(:fecha, :created_at)

そして私も変わりました

order('date ASC, created_at ASC')

ために

order(:fecha, :created_at)

0

Rails 6.1は、次のようなwhere条件の比較演算子に新しい「構文」を追加しました。

Post.where('id >': 9)
Post.where('id >=': 9)
Post.where('id <': 3)
Post.where('id <=': 3)

したがって、クエリは次のように書き換えることができます。

Note
  .where(user_id: current_user.id, notetype: p[:note_type], 'date >', p[:date])
  .order(date: :asc, created_at: :asc)

ここに、PRへのリンクがあります。ここに他の例を見つけることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.