如何在Ruby on Rails中实现用户帖子被点赞时的通知功能?
嘿,刚好我之前用Acts As Votable做过类似的点赞通知功能,给你一步步拆解具体做法,应该能直接套用!
假设你已经完成了Acts As Votable的基础配置(比如给Post模型加acts_as_votable,User模型加acts_as_voter),接下来按以下步骤来:
1. 创建通知模型
首先需要一个Notification模型来存储通知数据,包含接收用户、触发点赞的用户、关联帖子、通知类型和已读状态:
rails generate model Notification user:references actor:references post:references kind:string read:boolean default:false rails db:migrate
然后在模型里定义关联和常用作用域:
# app/models/notification.rb class Notification < ApplicationRecord belongs_to :user # 接收通知的帖子作者 belongs_to :actor, class_name: "User" # 点赞的用户 belongs_to :post # 快速筛选未读通知的作用域 scope :unread, -> { where(read: false) } end
2. 监听点赞事件,自动创建通知
Acts As Votable提供了after_like回调钩子,我们可以在Post模型里添加这个回调,当有用户点赞时自动生成通知:
# app/models/post.rb class Post < ApplicationRecord acts_as_votable belongs_to :user # 别忘了关联帖子作者哦 after_like :create_like_notification private def create_like_notification # *要注意:当点赞用户是帖子作者本人时,跳过通知创建,避免无效的自赞通知* return if voter == user Notification.create!( user: user, actor: voter, post: self, kind: "like" ) end end
这里的voter是Acts As Votable内置的方法,指向当前执行点赞操作的用户。
3. 处理通知的已读状态
创建一个Notifications控制器,用来展示用户的通知列表,并批量标记未读通知为已读:
# app/controllers/notifications_controller.rb class NotificationsController < ApplicationController before_action :authenticate_user! # 确保只有登录用户能访问 def index # 按创建时间倒序展示用户的所有通知 @notifications = current_user.notifications.order(created_at: :desc) # 批量标记未读通知为已读 @notifications.unread.update_all(read: true) end end
别忘了在config/routes.rb里添加路由:
Rails.application.routes.draw do # 其他路由... resources :notifications, only: [:index] end
4. 前端渲染通知列表
在视图里展示通知,比如app/views/notifications/index.html.erb:
<h3>你的通知</h3> <% if @notifications.empty? %> <p>暂无通知</p> <% else %> <% @notifications.each do |notification| %> <div class="notification-item <%= 'unread' unless notification.read %>"> <%= notification.actor.username %> 点赞了你的帖子: <%= link_to notification.post.title, post_path(notification.post) %> <span class="notification-time"><%= time_ago_in_words(notification.created_at) %> 前</span> </div> <% end %> <% end %>
还可以在导航栏添加未读通知的小红点提示,比如在app/views/layouts/application.html.erb:
<nav> <!-- 其他导航项 --> <%= link_to notifications_path do %> 通知 <% if current_user.notifications.unread.any? %> <span class="badge bg-danger"><%= current_user.notifications.unread.count %></span> <% end %> <% end %> </nav>
5. 可选优化:异步创建通知
如果你的用户量较大,点赞请求可能因为创建通知的同步操作变慢,这时可以用Active Job把通知创建逻辑异步化:
首先修改Post模型的回调:
# app/models/post.rb private def create_like_notification return if voter == user CreateLikeNotificationJob.perform_later(self, voter) end
然后生成异步任务:
rails generate job CreateLikeNotification
在任务里编写创建通知的逻辑:
# app/jobs/create_like_notification_job.rb class CreateLikeNotificationJob < ApplicationJob queue_as :default def perform(post, voter) Notification.create!( user: post.user, actor: voter, post: post, kind: "like" ) end end
这样一套下来,就能实现用户帖子被点赞时自动发送通知的功能啦,后续还可以扩展其他类型的通知(比如评论、关注),只需要修改kind字段和对应的触发逻辑就行。
内容的提问来源于stack exchange,提问作者Lashe

