125
99

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rails の ActiveRecord で SQL / Arel を使わずに以上・以下・より小さいの比較演算を実現する

Posted at

Rails の ActiveRecord を使っていると SQL ベタ書きしたり、Arel で書いたりする状況になることがある。そんな中で比較演算のケースは解決策があるのでメモっとく。

実行結果は Rails 4.2.1 で SQLite をデータベースとして利用しているときのもの。

範囲(BETWEEN 演算子)

where に Range で指定することができるこの方法は有名。コードが綺麗になるし、Rails と SQL の間の違和感もない。

Person.where(age: 20..35)

生成される SQL はこうなる。

SELECT "people".* FROM "people" WHERE ("people"."age" BETWEEN 20 AND 35)

以上(>= 演算子)

前述の Range で以上(>= 演算子)を表現するとこうなる。(数学的には正しいけどさ……。って呆れて読むのをやめる前に生成される SQL も見てね。)

Person.where(age: 20..Float::INFINITY)

生成される SQL はこうなる。エラーにならずにきちんと >= 演算子を含む SQL が出力される。

SELECT "people".* FROM "people" WHERE ("people"."age" >= 20)

以下(<= 演算子)

同様に Range で以下(<= 演算子)を表現するとこうなる。

Person.where(age: -Float::INFINITY..20)

生成される SQL はこうなる。エラーにならずにきちんと <= 演算子を含む SQL が出力される。

SELECT "people".* FROM "people" WHERE ("people"."age" <= 20)

より小さい(< 演算子)

同様に Range でより小さい(< 演算子)を表現するとこうなる。

Person.where(age: -Float::INFINITY...20)

生成される SQL はこうなる。エラーにならずにきちんと < 演算子を含む SQL が出力される。

SELECT "people".* FROM "people" WHERE ("people"."age" < 20)

より大きい(> 演算子)

残念ながら Range でより大きい(> 演算子)は表現できない。


実用的かどうかは微妙なところだけど、数学的には真っ当な気がするから、見慣れたら便利かもしれない。まあトリビアとして知っておいてもいいんじゃないかな。いきなりプロジェクトで使うとチームのエンジニアからクレームが来るかもしれないので慎重にw

参考文献

125
99
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
125
99

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?