使用 rails 开发点赞/收藏功能
极简版:Operator + Target 统一互动系统(点赞 / 收藏)
极简版:Operator + Target 统一互动系统(点赞/收藏)
核心:用「操作者(Operator)」和「目标物(Target)」统一,代码极致精简,只保留核心功能,新手也能秒懂。
一、1条命令生成所有(含点赞/收藏)
# 生成互动表:区分类型(type)、关联操作者(operator)和目标物(target)
rails g model Interaction type:string operator:references{polymorphic} target:references{polymorphic}
# 执行迁移(创建interactions表)
rails db:migrate
二、最终表结构(仅6个核心字段)
| 字段名 | 数据类型 | 一句话说明 |
|-----------------|------------------|------------|
| id | bigint(主键) | 互动记录ID |
| type | varchar(255) | 互动类型:Like(点赞)/ Favorite(收藏) |
| operator_id | bigint | 操作者ID(用户/商家ID) |
| operator_type | varchar(255) | 操作者类型:User(用户)/ Merchant(商家) |
| target_id | bigint | 目标物ID(文章/商品ID) |
| target_type | varchar(255) | 目标物类型:Article(文章)/ Product(商品) |
| created_at/updated_at | datetime(6) | 自动生成,无需管 |
三、3个核心模型(极简关联,无冗余)
# 1. 互动父表(所有互动的基础)
class Interaction < ApplicationRecord
belongs_to :operator, polymorphic: true # 操作者(用户/商家)
belongs_to :target, polymorphic: true # 目标物(文章/商品)
end
# 2. 点赞模型(继承父表,自动区分type="Like")
class Like < Interaction; end
# 3. 收藏模型(继承父表,自动区分type="Favorite")
class Favorite < Interaction; end
四、操作者/目标物模型(仅加2行核心关联)
1. 操作者模型(User示例,商家同理)
class User < ApplicationRecord
has_many :interactions, as: :operator # 所有互动(点赞+收藏)
has_many :likes, as: :operator # 仅点赞
has_many :favorites, as: :operator # 仅收藏
end
2. 目标物模型(Article示例,商品同理)
class Article < ApplicationRecord
has_many :interactions, as: :target # 所有互动(点赞+收藏)
has_many :likes, as: :target # 仅点赞
has_many :favorites, as: :target # 仅收藏
end
五、5个常用操作(控制台秒上手)
# 1. 准备数据(假设已创建用户和文章)
user = User.first
article = Article.first
# 2. 点赞
user.likes.create(target: article)
# 3. 收藏
user.favorites.create(target: article)
# 4. 查询:用户的所有点赞/收藏
user.likes # 点赞列表
user.favorites # 收藏列表
# 5. 判断:用户是否已给文章点赞/收藏
user.likes.exists?(target: article) # 已点赞?true/false
user.favorites.exists?(target: article) # 已收藏?true/false
六、极简控制器(以用户点赞为例,收藏同理)
# app/controllers/likes_controller.rb
class LikesController < ApplicationController
before_action :authenticate_user! # 登录校验
before_action :set_target # 获取要点赞的目标物(文章/商品)
# 点赞
def create
current_user.likes.create(target: @target) unless liked?
redirect_back fallback_location: root_path, notice: liked? ? "已点赞" : "点赞成功"
end
# 取消点赞
def destroy
current_user.likes.find_by(target: @target)&.destroy
redirect_back fallback_location: root_path, notice: "取消点赞"
end
private
# 获取目标物(支持文章/商品,需传target_type和target_id参数)
def set_target
@target = params[:target_type].constantize.find(params[:target_id])
end
# 简化判断:是否已点赞
def liked?
current_user.likes.exists?(target: @target)
end
end
七、1段路由配置(适配所有目标物)
# config/routes.rb
Rails.application.routes.draw do
# 点赞/取消点赞:支持文章、商品等所有目标物
post "/likes", to: "likes#create", as: :likes
delete "/likes", to: "likes#destroy", as: :like
end
这样就完成了极简版统一互动系统,代码少、逻辑清,后续加「关注」「转发」,只需新增 Follow < Interaction 模型,无需改表!
需要我帮你生成 前端点赞/收藏按钮的极简示例(ERB代码),直接复制就能用吗?