2

ユーザーはリソースを送信したり、コメントを投稿したりできます。

リソースとコメントを送信したユーザーを選択して、最も「アクティブ」なユーザーを表示し、リソースとコメントを最も多く送信したユーザーから結果を並べ替えます。

**Resource**
has_many :users, :through => :kits
has_many :kits
belongs_to :submitter, class_name: "User"

**User**
has_many :resources, :through => :kits
has_many :kits
has_many :submitted_resources, class_name: "Resource", foreign_key: "submitter_id"

**Kits**
belongs_to :resource
belongs_to :user

**Comments**
belongs_to :user

私はRailsのこの種のSQLに不慣れです。このレコードセットを取得するにはどうすればよいですか?

4

1 に答える 1

2

まず、コメントの関連付けをユーザーモデルに追加する必要があります。

has_many :comments

これを使用すると、最も簡単な解決策はこれを行うことです:

User.all.sort do |a,b|
   (a.submitted_resources.count + a.comments.count) <=> (b.submitted_resources.count + b.comments.count)
end

これは非常に遅くなるので、もっとうまくやりたいのであれば、カウンターキャッシュを追加したいと思うでしょう。移行の場合:

def up
  add_column :users, :submitted_resources_count, :integer
  add_column :users, :comments_count, :integer

  User.reset_column_information

  User.find_each do |u| 
    u.update_attributes! \
      :submitted_resources_count => u.submitted_resources.count,
      :comments_count => u.comments.count
  end
end

def down
  add_column :users, :submitted_resources_count
  add_column :users, :comments_count
end

この移行を実行すると、元のクエリを次のように変更できます。

User.select('*, (submitted_resources_count + comments_count) AS activity_level').order('activity_level DESC')

これにより、すべてのユーザーが適切な順序で非常に効率的に返されます。ボーナスとして、各ユーザーには、activity_level送信された正確なリソースとコメント数を示す読み取り専用属性が呼び出されます。

于 2012-07-12T08:25:44.380 に答える