如何在rails中向所有评论者发送通知?

问题描述 投票:1回答:1

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

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

comment.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

user.rb

 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

post.rb

 class Post < ApplicationRecord
    belongs_to :user
    validates :comment, presence: true
    validates :user_id, presence: true
    has_many :comments, as: :commentable
 end

comments_controller.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 [email protected]?
                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
mysql ruby-on-rails orm ruby-on-rails-5
1个回答
0
投票

您的第一个问题是在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
© www.soinside.com 2019 - 2024. All rights reserved.