Railsのwhere
メソッドは、ハッシュ内の範囲を取得して、範囲内の値を検索するクエリを生成できます。例えば:
_User.where(cash_money: 10..1000)
#=> SELECT `users`.* FROM `users` WHERE (`users`.`cash_money` BETWEEN 10 AND 1000)
_
これは、次のようなタイムスタンプでも使用できます。
_User.where(last_deposit: 10.days.ago..1000.days.ago)
#=> SELECT `users`.* FROM `users` WHERE (`users`.`last_deposit` BETWEEN '2014-05-19 14:42:36' AND '2011-09-02 14:42:36')
_
このようなハッシュ構文を使用して、数値に対して単純な「より小さい」または「より大きい」を実行できることがわかりました
_User.where(cash_money: 10..Float::INFINITY)
#=> SELECT `users`.* FROM `users` WHERE (`users`.`cash_money` >= 10)
_
_-Float::INFINITY
_でも同じことができます。
次のようなクエリを取得できるように、タイムスタンプでこれを行う方法はありますか?
_SELECT `users`.* FROM `users` WHERE (`users`.`last_deposit` >= '2014-05-19 14:42:36')
_
_Float::INFINITY
_または_Date::Infinity
_はどちらも_ArgumentError: bad value for range
_でエラーになるため、範囲を指定して使用することはできません。
_User.where('`users`.`last_deposit` >= ?', 10.days.ago)
_
同じSQLを生成しますが、これが文字列以外のオブジェクトで実行できる場合は、そうしたいと思います。
これはお粗末なことですが、Time.at(0)
とTime.at(Float::MAX)
を使用して範囲で実行できます。しかし、これらは同様にひどいSQLクエリをもたらす可能性があると私は感じています。
これはRails 5!
User.where(last_deposit: 10.days.ago..DateTime::Infinity.new)
sQLを生成します
SELECT `users`.* FROM `users` WHERE (`users`.`last_deposit` >= '2018-06-30 17:08:54.130085').
基本的なwhere
ハッシュ構文を使用してタイムスタンプのより大きいまたはより小さいクエリを生成する方法があるかのようには見えません。最も簡単で読みやすい方法は、私の質問のCurrent Simple Solution
に概説されています。
別の方法ではARelを使用しますが、あまり見られない呼び出しを行う必要があります。まず、ARクラスのARelテーブルへのハンドルを取得し、列にアクセスして、gt
以上、gteq
以上、lt
、および/またはlteq
への引数を持つwhere
メソッド以下。
上記の状況では、これは次のように行われます。
last_deposit_column = User.arel_table[:last_deposit]
last_deposit_over_ten_days_ago = last_deposit_column.gteq(10.days.ago)
User.where(last_deposit_over_ten_days_ago)
これを試しましたか?:
User.where(last_deposit: Time.at(0)...10.days.ago)
SQL:
SELECT `users`.* FROM `users` WHERE (`users`.`last_deposit` >= '1970-01-01 00:00:00' AND `users`.`last_deposit` < '2015-01-10 17:15:19')
適切な無限大を使用する必要があります。タイムスタンプはDateTime
ではなくDate
です。代わりに_DateTime::Infinity.new
_を使用するか、負の無限大の場合はDateTime::Infinity.new(-1)
を使用してください。