3

次の 2 つのレール モデルがあります。

class Profile < ActiveRecord::Base
  belongs_to :user

  has_many :votes, through: :user

  default_scope includes(:user)

end

class Vote < ActiveRecord::Base
  attr_accessible :by, :for

  belongs_to :by, class_name: "User"
  belongs_to :for, class_name: "User"

  validates :by, :for, presence: true

  validates_uniqueness_of(:by, scope: :for)
end

関連するユーザー レコードが受け取った「賛成」票の数に基づいてプロファイルを並べ替える「トップ」スコープをプロファイルに作成しようとしています。

投票は、ユーザーがユーザーのために作成します。「by」列は投票したユーザーを示し、「for」列は投票したユーザーを示します。最も多くの票を獲得したユーザーのプロファイルを取得しようとしています。

これは私がこれまでに得たものです:

   scope :top,
    select("profile.*, count(votes.id) AS votes_count").
    joins(:votes, :user).
    order("votes_count DESC")

これは、次のエラーでは機能しません。

ActiveRecord::StatementInvalid: PG::Error: エラー: 列 "votes_count" が存在しません

また、「for」列は考慮されません

誰でも私を助けることができますか?

4

2 に答える 2

8

あなたはグループ化を欠いていると私は信じています。実行しようとしているクエリは次のとおりです。

select profiles.*, count(votes.id) as votes_count 
  from profiles 
  left join votes on votes.for_id = profiles.user_id 
  group by profiles.id 
  order by votes_count desc;

それでは、これをActiveRecordスコープに変えましょう:

scope :top, joins('left join votes on votes.for_id = profiles.user_id').
  select('profiles.*, count(votes.id) as votes_count').
  group('profiles.id').
  order('votes_count desc')
于 2013-03-18T14:40:48.870 に答える
2

ActiveRecord の方法

Profile.joins(:votes).group("profiles.id").order("count(profiles.id) DESC")
于 2015-11-10T04:37:32.320 に答える