0

User と Task の 2 つのクラスがあるとします。タスクはユーザーに属し、優先度 (1 から 3 までの整数、または nil) を持っています。

class User < ActiveRecord::Base
    has_many :tasks

class Task < ActiveRecord::Base
    belongs_to :user
    attr_accessible :priority # Integer between 1 and 3, or nil

タスク数が最も多く、優先度が最も高い上位 10 人のユーザーを提示したいと考えています (最初に優先度が高く、次に中、次に低く、未評価の順に並べ替えます)。別の方法を考えましたが、これを処理するためのきれいな方法が見つかりません。

パフォーマンスを制限するために、コントローラーのメソッドで複雑な SQL リクエストを使用することを最初に考えました。

User.joins(:tasks).count(:all, :group => ["tasks.user_id", "priority"])

ただし、結果を並べ替えるのは簡単ではなく、最終的に並べ替えに 2 つのループを使用し、ユーザーをレンダリングするために別のループを使用する必要があります。さらに、この種の方法は、モデルではより論理的であると思います。

どう思いますか?これを処理する最もクリーンな方法は何ですか?

4

2 に答える 2

1

以下を使用できます。これを試してください:

User.select("users.id, count(tasks.id) as task_count").
joins(:tasks).group("users.id").order("task_count desc").first(10)

これはうまくいくと思います。テストされていませんが。

于 2012-09-10T18:02:06.233 に答える
1

私の理解が正しければ、最も優先度の高いタスクの数が最も多いユーザーを並べ替えますか? したがって、シナリオでは:

  • ユーザー A には 3 つのタスクがあり、優先度 1 の 2 つと優先度 3 の 1 つがあります。
  • ユーザー B には 2 つのタスクがあり、そのうち 2 つは優先度 3 です
  • ユーザー C には優先度 2 のタスクが 1 つあります

そして、出力は次のようになると思いますか? B、A、C?

タスクの優先度を合計して、それで並べ替えるだけです。

User.joins(:tasks).group("users.id").order("SUM(tasks.priority) DESC").first(10)

頭のてっぺんから書いているので、SQL は少しずれているかもしれませんが、うまくいけば、その考えが理解できると思います。ここでの秘訣は SQL ではなく、ソートに使用する重み関数です。

于 2012-09-10T18:04:54.280 に答える