Closed4

rubocopにおいてRails/PluckInWhereを有効化するかどうかが悩ましい問題の解決法

Matsukura YukiMatsukura Yuki

以下のようなコードがあったとすると、

ids = User.where(company_id: ).pluck(:id)

rubocop -Aを実行してauto fixを掛けると以下のように変更されてしまう。

ids = User.where(company_id: ).select(:id)

しかしながら返り値が変わるので等価ではないので要注意です。
変更前はArrayだが変更後は、ActiveRecord::Relationです。

Rubocopの仕様書を見るとUnsafeなので、-A オプションを使ったときだけ強制的に自動修正されます。
-A を多用する方は要注意です。

Matsukura YukiMatsukura Yuki

このルールは以下のCopで定義されている。
Rails/PluckInWhere

単純に、オフにすれば回避できるのですが、オフにしたところで今度は本当にパフォーマンスが改善できる可能性のあるコードを見つけられなくなってしまう問題が発生します。

極端な例ですが、以下のようなコードがあったとすると、

Post.where(user_id: User.where(company_id: ).pluck(:id))

以下のように書き換えたほうがパフォーマンスが良いのでrubocopに見つけてほしいところではあります。

 Post.where(user: User.where(company_id: ))

なので、このように設定しておくのが良さそうです。

Rails/PluckInWhere:
  Enabled: true
  AutoCorrect: false
Matsukura YukiMatsukura Yuki

以下のようなコードはautofixで修正しても等価です。

User.where(id: Project.where('id < 100').pluck(:user_id))

変更後

User.where(id: Project.where('id < 100').select(:user_id))
Matsukura YukiMatsukura Yuki

以下の設定を.rubocop.ymlに入れることで運用することにしました。

Rails/PluckInWhere:
  Enabled: true
  AutoCorrect: false
このスクラップは6日前にクローズされました