如何使用Noticed gem创建动态参数 优化通知模块重复代码
Rails Noticed 通知功能冗余代码优化方案
核心思路是把散落在视图里的分支判断逻辑下沉到模型层封装,视图层只负责渲染,抽公共组件实现跨场景复用。
1. 模型层封装统一调用方法
在数据库存储的Notification模型中封装通用方法,把原来重复的post/conversation判断、用户获取、头像/用户名兜底逻辑全部收敛,避免视图层写分支判断:
# app/models/notification.rb class Notification < ApplicationRecord include Noticed::Model belongs_to :recipient, polymorphic: true # 获取通知绑定的业务主体(帖子/会话/后续新增的其他资源) def notifiable_resource @notifiable_resource ||= params[:post] || params[:conversation] end # 获取触发通知的对应用户 def actor @actor ||= notifiable_resource&.user end # 返回处理好的头像地址,自动兜底默认头像 def actor_avatar_url(size: 35) return "no-photo-avatar.png" if actor.blank? avatar_url_for(actor, size: size).presence || "no-photo-avatar.png" end # 返回触发用户的显示名称,兜底匿名 def actor_display_name actor&.full_name || "匿名用户" end # 封装通知自带的消息、跳转链接,避免视图重复调用to_notification def message to_notification.message end def target_url to_notification.url end end
2. 抽离公共视图组件
把通知条目的渲染逻辑抽成全局可复用的partial,导航栏下拉、独立通知页都可以直接调用,不用重复写渲染逻辑:
新建partial文件 app/views/notifications/_notification_item.html.slim:
.notification-item.d-flex.align-items-center.gap-2.py-2 = image_tag notification.actor_avatar_url, class: "rounded-circle", width: 35, height: 35 .notification-content = link_to notification.message, notification.target_url | by: span.actor-name = notification.actor_display_name
在所有需要渲染通知列表的位置,直接遍历渲染partial即可:
- notifications.each do |notification| = render "notifications/notification_item", notification: notification
3. 后续扩展兼容规则
如果后续新增其他类型的通知(比如评论通知、点赞通知),不需要修改视图层代码,只需要对应调整方法逻辑即可:
- 如果新通知的触发用户仍然是绑定资源的
user关联,只需要在notifiable_resource方法中新增params键的判断即可,比如新增params[:comment]的匹配 - 如果新通知的触发用户获取逻辑特殊(比如评论通知的触发者是comment的author而非user),直接在对应的Noticed通知类中重写同名方法即可,自动覆盖模型层的默认逻辑,示例:
# app/notifications/comment_notification.rb class CommentNotification < Noticed::Base # 重写actor获取逻辑,其他方法自动复用通用逻辑 def actor params[:comment]&.author end end
这种实现方式完全消除了视图层的重复分支判断,后续修改头像规则、名称显示、跳转逻辑时只需要修改一处代码,不会出现漏改、多改的问题。
内容的提问来源于stack exchange,提问作者nelsonchaves
相关产品推荐
相关产品推荐

