日刊 あおのうま Vol.2645(2018.02.11)【専念できること】

投稿者: | 2018/02/11

環境 と 結果

何を言っているかわけがわからないと思いますが、仕事の話です。
要は先週そこそこ苦しんでいた仕事が週末ノマドで呆気なく解消しつつあるので、環境って大きいなというお話。

以下、詳細。


Rails でモデルのレコードをフィルタリングする際は、クラスメソッドよりもscope を使う方が便利ですね。
何故なら、scope はメソッドチェーンとして結果をつないで行けますし、抽出条件にnil を渡した場合は特に何も書かなくてもall を返してくれるからです。

これを使うと、複数条件を動的に組み合わせたAND 抽出が可能になります。

ただし、注意点として引数に配列を渡す際は要注意です。
scope は引数にnil を渡されると全件レコードall を返しますが、nil 入りの配列[nil] を渡されると「nil を1つ格納した配列」を引数としますので、IS NULL な検索を行ってしまいます。
これを避けたい場合は、reject を使ってnil を除去してから、三項演算子あたりで明示的にall を返してやるのが良さそうです。
こんな感じ。

# 引数としてオプショナル(省略可能)なnames を持つ
scope :names, -> (*names) {
  names.extract_options!
  # 引数*names が省略された場合、names にはnil が格納された配列 [nil] が入る
  # そこでnames の中身に対してnil と空白を除去するreject をかけ、それでも中身が残っていれば
  # names でwhere フィルタをかけた結果を返し、中身が残っていなければ全件を返す
  names.reject(&:blank?).present? ? where(name: names) : all
}

ここいらの書き方が出来る様になったお陰でレコードの抽出が随分と楽になりそう。
あとは任意のフィルタリング結果が0件だった場合、再帰的に遡ったり進んだりして次点のレコードを取ってくるscope と、それらの差分を積算して行くメソッドを次数1に収めた計算量で実装するだけです。

それにしても、先週そこそこ苦しんだ実装が週末にノマド作業で呆気なく書けちゃうと、職場で仕事するのがアホらしくなってきますね。
やはり割り込みが無い環境って大事だなあ。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください