0

次のようなメソッドを定義して、カスタム ソートを ActiveRecord モデルに追加しました。

class MyClass < ActiveRecord::Base
  belongs_to :parent_model #this would be the many in a has_many relationship

  def <=>(other)
    self.att <=> other.att
  end
end

比較で実際に使用されているロジックは、この例よりも少し複雑であり、SQL で実現できるものではありません。

このクラスは、包含モデルのネストされたフィールドとしてのみ使用されるため、結果セットをソートする簡単な場所はないようです。コントローラーでは、:my_class は熱心な読み込みのためのインクルードの一部ですが、ビューまで (form.fields_for :my_class を実行するとき) オブジェクト配列で他に何もしません。私が本当に望んでいるのは、論理ソートを使用して default_scope と同等のことを実行できるようにすることですが、それは不可能だと思います。現在、私の唯一のオプションは、この結果をソートするためだけにコントローラーに余分な行を追加することのようですが、それは正しいことではないようです。

ここで見逃しているもっとエレガントなものはありますか?

4

2 に答える 2

0

これが機能するかどうかはテストできませんでしたが、次のような匿名の関連付けモジュールを試すことができます。

class ParentModel < ActiveRecord::Base
  has_many :my_class do
    # Sort the result set...  
  end
end
于 2009-11-30T17:27:37.887 に答える
0

これを行う最良の方法は、SQL ソート用にデータベースをセットアップし、スコープ/検索で :order オプションを指定することです。読み込まれたオブジェクトの数が特定のしきい値を超えると、コントローラーで並べ替えを行うと非常にコストがかかります。特に、リストされるレコードの数を制限しようとしている場合。

並べ替えが実際にこの列を並べ替えるよりも複雑な場合。データベースにソート キー列を追加することを検討する必要があります。通常、オブジェクトの状態から派生した 2 つの値を比較することを含む、何らかの順序付け方法を明確に考え出しました。before_create/save コールバックを使用してデータベースの新しい sort_key 列にその値を格納し、それによって結果を並べ替えるだけです。

タスクの例:

優先順位が付けられますが、期日が金曜日であるレコードは、他のすべてのレコードよりも前にリストされます。sort_key 列を使用します

class Task < ActiveRecord::Base
  def calculate_sort_key
    key = due_date.wday == 5 ? "0" : "1"
    key += prioirty.to_s
    self.sort_key = key.to_i
  end

  before_save :calculate_sort_key
  default_scope :order => "sort_key"
end
于 2009-11-30T17:21:37.223 に答える