業務開発でRailsを使用しており、ORMもよく使用しているのですが、業務開発を通して知った where
句の文法的なのをここで紹介していきます。
where(column: value)
これはRailsのwhere句の一番オーソドックスな書き方だと思います。
whereをメソッドチェーンで繋げていけば and
句となり条件をより絞ることができます。
# e.g.
User.where(id: 1)
User.where(gender: "man").where(name: "hoge")
where(column: [value])
これはいわゆる where in
句の書き方で、 or
検索をかけたい時は基本的にこの書き方が一番いい気がします。
若干話が変わりますが、SQLアンチパターンにおいて、 or
検索はインデックスが効かない where
句の書き方ですが、 where in
句はインデックスが効く書き方なので、もし or
のような和集合条件でインデックスが効く検索をしたい場合は where(column: [value])
のパターンが個人的には一番いい気がします。
DBのインデックスについては、下記の記事が非常にわかりやすいと思います。
# e.g.
User.where(id: [1, 2, 3])
User.where(gender: [1, 2]).where(name: ["hoge", "ruby"])
where('RAW SQL')
これは引数を全て文字列にすることで、実際のSQLの構文を用いた where
句を書くことができます。しかし、これは避けされるのなら基本的に避けたい書き方かなと思います。SQLインジェクションに繋がりかねない書き方という点、Rubyの特徴に合わせたORMの利点が欠けてしまう点、という二つから個人的にはそこまでおすすめはしないです。
が、やはり複雑な条件をつけなければならない時はいつかくるし、その時は仕方なく使っています。
# e.g.
User.where('id = 1')
User.where('gender in (1, 2)').where("name = 'hoge'")
where('RAW SQL ?', value)
先ほどの生SQLに、動的な値を入れたい場合に使用する書き方です。
?
を生SQLの部分に記述すると、その後引数に入れた値が入るので、動的に検索することが可能になり便利です。この記法は、サニタイズされた値が ?
の部分に入るので、SQLインジェクションの可能性が非常に低いです。
# e.g.
User.where("id = ?", 1)
# ?をつけた分だけ、動的な値を入れることができます
User.where("gender = ? and gender = ?", 1, 2)
where('RAW SQL ?', [value])
これはほぼ where in
句専用と言っても個人的には過言ではない書き方です。てかもしかしたら where in
専用な気がしてきました。?
に、配列の要素を展開してSQLを作ってくれます。
User.where('id in (?)', [1, 2, 3, 4])
User.where('gender in (?)', [1, 2])
where('column': value)
この記事を書く直近でこの書き方を知ったのですが、個人的に結構衝撃でした。
というのも、結合したテーブルのレコードにも対して where
句が書けるからです。今までは上記で紹介した where('RAW SQL')
を使って書いていたので、結合したテーブルの条件場面ではよく使用しています。
# e.g.
User.joins(:posts).where('user.id': 1).where('post.id': [1, 2, 3])