【发布时间】:2017-11-18 12:38:35
【问题描述】:
我在通过 ActiveRecord 查询创建类方法时遇到困难:
我创建了一个名为 popular_users 的类方法来按用户数量对用户进行排序,但它没有返回任何结果。我相信问题在于friend_id: self。如果我使用friend_id: User.first 在rails 控制台中进行测试,它可以工作。 (friend_id是被关注者的id)
class User < ApplicationRecord
# received friend (ie a follower): other user sends a request which has been accepted by current user
has_many :friendships
has_many :received_friendships, class_name: "Friendship", foreign_key: "friend_id"
has_many :received_friends, -> { where(friendships: { accepted: true}) }, through: :received_friendships, source: :user
def self.popular_users
self.joins(:friendships)
.where(friendships: {accepted: true, friend_id: self})
.group("users.id")
.select("users.id, count(friendships) AS followers_count")
.order("followers_count DESC")
end
我尝试了以下方法,但它导致了这个错误:
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: 语法错误 在“SELECT”处或附近
def self.popular_users
self.joins(:friendships)
.group("users.id")
.select("SELECT COUNT(friend_id) FROM friendships WHERE (user_id = :user_id AND accepted = 't')) AS followers_count")
.order("followers_count DESC")
end
架构:
create_table "friendships", force: :cascade do |t|
t.integer "user_id"
t.integer "friend_id"
t.boolean "accepted", default: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "name"
end
更新:这是我的回答
def self.popular_users
self.joins("RIGHT JOIN friendships ON friendships.friend_id = users.id AND friendships.accepted = 't'")
.group("users.id")
.select("users.id, count(users.id) AS followers_count")
.order("followers_count DESC")
end
例如在 Rails 控制台中测试:
Friendship.create(user_id: 1, friend_id: 2, accepted: true)
Friendship.create(user_id: 4, friend_id: 2, accepted: true)
Friendship.create(user_id: 5, friend_id: 2, accepted: true)
Friendship.create(user_id: 1, friend_id: 3, accepted: true)
Friendship.create(user_id: 2, friend_id: 3, accepted: true)
在控制台输入User.popular_users后返回的结果是#<ActiveRecord::Relation [#<User id: 2, followers_count: 3>, #<User id: 3, followers_count: 2>]>
【问题讨论】:
-
您想用
.where( friendships: { friend_id: self })实现什么目标?我看起来您只要求与某个(当前?)用户有友谊的用户。 -
我试图将每个用户拥有的关注者数量相加(例如,如果用户接受了另一个用户发送的友谊,则关注者计数 = 1),然后按关注者降序对用户进行排序数数。 (如人气榜/记分牌)
-
感谢您的澄清。请查看我发布的答案。
标签: ruby-on-rails ruby activerecord