在我的应用中,当User
在Comment
中生成Post
时,会生成Notifications
,将该评论标记为未读。
class Notification < ActiveRecord::Base
belongs_to :user
belongs_to :post
belongs_to :comment
class User < ActiveRecord::Base
has_many :notifications
class Post < ActiveRecord::Base
has_many :notifications
我正在创建一个索引页面,其中列出了用户的所有帖子以及仅针对该用户的每个帖子的通知计数。
# posts controller
@posts = Post.where(
:user_id => current_user.id
)
.includes(:notifications)
# posts view
@posts.each do |post|
<%= post.notifications.count %>
这不起作用,因为它计算所有用户的通知。在不在每个帖子中运行单独查询的情况下,为单个用户计算通知的有效方法是什么?
答案 0 :(得分:1)
# posts controller
@posts = Post.where(…
@notifications = Notification.where(
:user_id => current_user.id,
:post_id => @posts.map(&:id),
:seen => false
).select(:post_id).count(group: :post_id)
# posts view
@posts.each do |post|
<%= @notifications[post.id] %>
似乎足够有效。
答案 1 :(得分:0)
你可以这样做:
@posts=Post.joins(:notifications).where('notification.user_id' => current_user.id)
其中notification.user_id
是current_user
答案 2 :(得分:0)
我建议创建一个小类来封装通知集合的逻辑:
class NotificationCollection
def self.for_user(user)
new(Notification.where(user_id: user.id))
end
def initialize(notifications)
@notifications = notifications
end
include Enumerable
def each(&block)
@notifications.each(&block)
end
def on_post(post)
select do |notification|
notification.post_id == post.id
end
end
end
然后,在您的控制器上:
@user_notifications = NotificationCollection.for_user(current_user)
@posts = Post.where(user_id: current_user.id)
最后,在你看来:
@posts.each do |post|
<%= @user_notifications.on_post(post).count %>
end
这样,您只需要为每个用户执行一次通知查询 - 而不是像在数据库上执行COUNT()
一样,但如果单个用户的通知低于数百,则应该足够。< / p>