Rails 实现评论点赞功能方案咨询:调整现有模型还是新建独立模型?
Rails 点赞功能实现方案选型解答
结论
优先使用你已有的多态关联实现评论点赞,不需要修改现有点赞表结构,也不需要单独创建评论点赞模型,这是普通博客场景下的最优解。
两种方案的问题分析
方案1:现有点赞模型新增comment_id字段
- 该方案不合规,属于对多态关联的误用,完全没有必要
- 不会破坏现有多态关联,但会产生严重的数据冗余:多态关联本身通过
likeable_type(存储关联模型类名)和likeable_id(存储关联模型主键)两个字段实现对任意模型的关联,不需要为每个关联的模型单独新增外键字段 - 后续维护容易出现数据不一致问题,比如同一条点赞记录同时赋值了
blog_id、comment_id,会导致关联逻辑混乱
方案2:单独创建评论点赞模型
- 该方案可以正常运行,但普通博客场景下不是最优选择
- 优点:两种点赞逻辑完全隔离,后续如果博文点赞和评论点赞需要扩展完全不同的业务字段、走完全独立的业务流程,不会互相影响,单表查询不需要加
likeable_type过滤条件,性能略高 - 缺点:大量重复代码,两个点赞模型的核心逻辑完全一致,后续修改通用规则(比如新增点赞频次限制、点踩功能)需要同步修改两个模型,维护成本高,后续如果要给其他模块(比如用户主页、相册)加点赞功能,还要新增更多点赞表
最优实现方案
你现有的多态点赞模型完全可以复用,只需要给评论模型补充多态关联即可,不需要修改任何表结构:
现有代码(你已经实现的部分)
# app/models/like.rb class Like < ApplicationRecord belongs_to :user belongs_to :likeable, polymorphic: true # 建议加唯一校验,避免同一个用户重复点赞同一内容 validates :user_id, uniqueness: { scope: [:likeable_type, :likeable_id] } end # app/models/blog.rb class Blog < ApplicationRecord has_many :likes, as: :likeable # 其他原有关联逻辑 end
新增评论点赞需要补充的代码
# app/models/comment.rb class Comment < ApplicationRecord has_many :likes, as: :likeable # 其他原有关联逻辑 end
调用示例
# 给博文创建点赞 @blog.likes.find_or_create_by(user: current_user) # 给评论创建点赞 @comment.likes.find_or_create_by(user: current_user) # 取消点赞逻辑通用 @like.destroy
可选优化
如果之前建likes表的时候没有加联合唯一索引,建议补充迁移避免重复数据:
# db/migrate/xxx_add_unique_index_to_likes.rb class AddUniqueIndexToLikes < ActiveRecord::Migration[7.0] def change add_index :likes, [:user_id, :likeable_type, :likeable_id], unique: true end end
特殊场景选型建议
如果后续你明确需要给博文点赞和评论点赞增加完全独立的扩展字段(比如博文点赞需要记录用户点赞时的分享渠道、评论点赞需要记录是否同时推荐该评论),且两种点赞的统计、查询逻辑完全独立,可以选择方案2单独建表。
内容的提问来源于stack exchange,提问作者Abhishek Singh
相关产品推荐
相关产品推荐

