Rails多态关联下如何通过关联模型ID删除Favorite
实现多态收藏的类型+ID删除逻辑
1. 配置路由
首先在config/routes.rb中添加自定义删除路由,匹配你需要的/favorites/ata_public/2格式:
delete '/favorites/:favoritable_type/:favoritable_id', to: 'favorites#destroy', as: :favorite_by_type
:favoritable_type:接收收藏对象的类型(如ata_public):favoritable_id:接收收藏对象的IDas: :favorite_by_type:生成路由辅助方法,方便视图调用
2. 完善FavoritesController的destroy方法
结合你的数据库结构(包含user_id、favoritable_type、favoritable_id字段),修改控制器代码,确保只删除当前用户的对应收藏:
class FavoritesController < ApplicationController before_action :set_favorite, only: [:destroy] def destroy @favorite.destroy respond_to do |format| format.html { redirect_to favorites_url, notice: '收藏已取消' } format.json { head :no_content } end end private def set_favorite # 将下划线格式的类型转成模型类名(如"ata_public" → "AtaPublic") favoritable_type = params[:favoritable_type].classify # 校验类型合法性,防止恶意参数 unless Object.const_defined?(favoritable_type) redirect_to favorites_url, alert: '无效的收藏类型' return end # 定位当前用户的目标收藏 @favorite = current_user.favorites.find_by( favoritable_type: favoritable_type, favoritable_id: params[:favoritable_id] ) # 处理收藏不存在的情况 unless @favorite redirect_to favorites_url, alert: '该收藏不存在' end end end
3. 视图中的删除链接示例
用路由辅助方法生成符合要求的删除链接:
<%# 取消AtaPublic对象的收藏 %> <%= link_to '取消收藏', favorite_by_type_path('ata_public', ata_public.id), method: :delete, data: { confirm: '确定要取消收藏吗?' } %> <%# 取消AtaObject对象的收藏 %> <%= link_to '取消收藏', favorite_by_type_path('ata_object', ata_object.id), method: :delete, data: { confirm: '确定要取消收藏吗?' } %>
关键注意点
- 权限控制:通过
current_user.favorites限定只操作当前用户的收藏,避免误删他人数据 - 安全校验:用
Object.const_defined?验证传入的类型是否对应真实存在的模型,防止注入攻击 - 错误处理:对无效类型、不存在的收藏做跳转提示,提升用户体验
内容的提问来源于stack exchange,提问作者Roberto da Silva
相关产品推荐
相关产品推荐

