使用 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代码),直接复制就能用吗?