2016-10-18 3 views
1

MySqlを使用してRails 5アプリケーションをバックエンドとして作成しました。
"disk_size"フィールドを持つ "Server"モデルがあり、disk_sizeフィールドはvarcharで、値は "10 GB"、 "512 MB"のように格納されています。私は、 "512 MB"、 "10 GB"のような昇順でdisk_sizeフィールドによる注文データの結果を求めます。文字列として格納されている "ディスクサイズ"の値に基づいてデータを並べ替える方法は?

+0

これはhttp://stackoverflow.com/questionsを助けます/ 4605627/how-to-sort-mysql-coloumn-that-has-data-in-bytes-kb-mb-gb。 – dnsh

答えて

1

これは、文字列のサイズを計算する際にオーバーフローが発生すると思います。また、SQLを使用してこれらを注文することはできません。

より良い方法はバイト単位で格納するため、ソートできる整数になります。

サイズを印刷する場合は、number_to_human_sizeヘルパーを使用してください。 docs

などを参照してください。

irb(main):003:0> size = 10_000_000 
=> 10000000 
irb(main):004:0> number_to_human_size(size) 
=> "10 MB" 

EDIT:

アンドレイDeinekoによると、これは答えませんでした。

例えば「ファイルサイズ」という名前のクラスを作成します(あなたはapp/models/でそれを置くことができる):

class FileSize 
    include Comparable 

    UNITS = { 
    "MB" => 1_000_000, 
    "GB" => 1_000_000_000, 
    # ... 
    } 

    def initialize(str) 
    @str = str 
    end 

    def to_bytes 
    count, unit = @str.split(" ") 
    if UNITS.key?(unit) 
     count.to_i * UNITS[unit] 
    else 
     raise "Don't know unit #{unit.inspect}, please specify." 
    end 
    end 

    def <=>(other) 
    to_bytes <=> other.to_bytes 
    end 

    def inspect 
    @str 
    end 

    def to_s 
    @str 
    end 
end 
だからここ

は(これを解決するために非常に非常に非常に長いSQLクエリなし)ルビー方法です

UNITS定数にあなたが所有しているすべてのユニットを記入してください。

あなたはActiveRecordのを使用している場合は、あなたのモデルのごゲッターを上書きすることができます

class MyModel < ApplicationRecord 
    def disk_size 
    FileSize.new(super) 
    end 
end 

だから、あなたがこれを行うことができます:

MyModel.where(something: "is").sort_by(&:disk_size) 
+0

それは私が完全に同意する良い勧告ですが、それは質問への答えではありません - 列はすでに文字列です –

+0

それは答えではありませんか? – siegy22

+0

DBスキーマの変更を含む代替案を提案しましたが、現在の設定の解決策ではありません(この方法が理にかなっていますが)。あなたがしなければならないことは、現在の問題**と**を解決する方法を提供し、より良い方法を提案します。これがこのサイトの仕組みです。 「あなたが持っているものをすべて捨てて、このようにやり直す」という質問に答えることはできません。たとえばOPがDBスキーマを変更できないような状況があるかもしれません。そのような場合にあなたの答えはどのように適格になりますか? –

関連する問題