質問: railsのActiveRecord で、データをソートしたいと考えております。 例えば、下記のようなデータがあったとします。 "1Mbyte", "2Kbyte", "3byte" M, K などの単位を考慮してソートしたいです。 "3byte", "2Kbyte", "1Mbyte" と並ぶのが理想です。 配列に入れて、数値に置き換えて、ソートしておりましたが、数万件のデータがありますので、より速いやり方がないか、お知恵をお借りしたいです。
回答: DB上に "1Mbyte", "2Kbyte", "3byte" のように入っているのを、ActiveRecord に取得した時点でソートがかかっていて欲しい、ということでしょうか。 小数点を含まない、という前提であれば、抽出時に以下のように部分的に置き換える | 置き換え前 | 置き換え後 | | --- | --- | | byte | | | Kbyte | 000 | | Mbyte | 000000 | と、 | 置き換え前 | 置き換え後 | | --- | --- | | 1Mbyte | 1000000 | | 2Kbyte | 2000 | | 3byte | 3 | となるので、order() を使ってうまくソートできそうではありますが... ※ただしこれだと "3071byte" > "3Kbyte" になってしまいます。より確実にするにはきちんと演算しないとダメです 基本、RoR というより DB 側の領分ですね。 もう一つの手としては、ActiveRecord の戻り値となるオブジェクトに、 あらかじめ <=> 演算子を再定義(これが容量表現を解釈して数値化して比較する)してやって、それを使って sort_by() かけてやるとか。 ※ソートの比較関数を定義してやるわけです ActiveRecord の定義 ``` class Record < ApplicationRecord def <=>(other) // self.~ と other.~ を使って、比較をする // 最終的に self の方が前に来るなら -1 を、後に来るなら 1 を、一致するなら 0 を return する end end ``` こんな風に ActiveRecord に <=> 演算子を定義してやります。 そうすると ActiveRecord を(配列で)全件取り出したところで、配列.sort() としてやれば、いちいち変換などせずとも(比較関数の中で変換することで)解釈してソートしてくれます。