繁体   English   中英

如何在rails中向所有评论者发送关于多态评论的通知?

[英]How to send notifications to all commentors on polymorphic comments in rails?

我正在使用多态关联进行评论。 我想向所有评论帖子的用户发送通知。

  • 假设user1发布了一个帖子。
  • User2对此发表评论。
  • User1收到通知 (users = User.joins(:posts).where(:posts => {id: params[:post_id]})) “ User2 发表了评论
  • 再次, User1评论。
  • 现在, User2应该收到通知(users= ????)
  • 如果用户 2、用户 3、用户4发表评论,则所有相关用户都应该收到通知。

评论.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM