[英]How to send notifications to all commentors on polymorphic comments in rails?
我正在使用多态关联进行评论。 我想向所有评论帖子的用户发送通知。
评论.rb
class Comment < ApplicationRecord
belongs_to :user
belongs_to :commentable, polymorphic: true
has_many :comments, as: :commentable
validates :comment, presence: true
after_create :notifications
def notifications
#Create Notification
users = ????
(users-[@current_user]).each do |user|
Resque.enqueue(NotifyJob, Notification.create(
recipient: user,
actor: @current_user,
action: "posted",
notifiable: @comment))
end
end
end
用户名
class User < ApplicationRecord
has_many :posts, dependent: :destroy
has_many :comments, as: :commentable, dependent: :destroy
has_many :notifications, foreign_key: :recipient_id, dependent: :destroy
end
后.rb
class Post < ApplicationRecord
belongs_to :user
validates :comment, presence: true
validates :user_id, presence: true
has_many :comments, as: :commentable
end
评论控制器.rb
module Api
module V1
class CommentsController < ApplicationController
skip_before_action :verify_authenticity_token
before_action :authorize_request
before_action :find_commentable
def new
@comment = Comment.new
end
def create
@comment = @commentable.comments.new(comment_params)
@comment.user = @current_user
if @comment.save
render json: @comment, status: :created
else
render json: { errors: @comment.errors.full_messages },
status: :unprocessable_entity
end
end
def show
@comment = Comment.find(params[:id])
if !@comment.nil?
render json: @comment, status: :ok
else
render json: {errors: @comment.errors.full_messages}, status: :unprocessable_entity
end
end
private
def comment_params
params.permit(:comment)
end
def find_commentable
@commentable = Comment.find_by_id(params[:comment_id]) if params[:comment_id]
@commentable = Post.find_by_id(params[:post_id]) if params[:post_id]
end
end
end
end
你的第一个问题是在User
模型中。 你有
has_many :comments, as: :commentable, dependent: :destroy
但是Comment
模型belongs_to :user
并且有user_id
,这意味着在User
has_many :comments, dependent: :destroy
在这种情况下,您可以使用User.first.comments
轻松获取所有用户评论
第二个是回调。 Vyacheslav Loginov 关于将这种复杂逻辑置于控制器操作中的错误做法是正确的,但回调也不是好的做法。 不确定他们中的哪个更糟。 您将在每次评论创建时创建通知,即使是从控制台。 将在您创建 commnet 的每个测试设置中创建通知。 不确定这是否是您真正想要的。
更好的选择是创建单独的 ServiceObject 来处理通知
class CommentsController < ApplicationController
def create
@comment = @commentable.comments.new(comment_params)
@comment.user = @current_user
if @comment.save
NotificationSender.new(@comment).comment_notification
render json: @comment, status: :created
else
render json: { errors: @comment.errors.full_messages },
status: :unprocessable_entity
end
end
end
class NotificationSender
def initialize(resource)
@resource = resource
end
# you can add here all other notifications as methods
def comment_notification
users = User.where(id: @resource.commentable.comments.pluck(:user_id)).
where.not(id: @resource.user_id)
users.each do |user|
Resque.enqueue(
NotifyJob,
Notification.create(
recipient: user,
actor: @resource.user,
action: "posted",
notifiable: @resource
)
)
end
end
end
我没有做太多改变。 我只是做了这样的改变:
评论.rb
class Comment < ApplicationRecord
belongs_to :user
belongs_to :commentable, polymorphic: true
has_many :comments, as: :commentable
validates :comment, presence: true
private
after_commit :create_notifications, on: [:create]
#Create Notification
def create_notifications
commentable = self.commentable
commentors= Comment.where(commentable: commentable).pluck(:user_id)
users = User.find(commentors)-[self.user]
users.each do |user|
Resque.enqueue(NotifyJob, Notification.create(
actor: self.user,
recipient: user,
action: "posted",
notifiable: self.commentable))
end
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.