如何编写Ruby Discard模块的可复用补丁以避免Rails项目代码重复
实现方案
问题原因
原实现错误主要集中在两点:
- Discard::Model是基于ActiveSupport::Concern实现的Rails模型增强模块,需要在目标模型类的上下文下引入才能正确注入类属性、回调等能力,不能直接在自定义模块的定义阶段提前include/extend
- 没有按Rails concern的规范组织代码,导致重写的discard方法优先级低于原Discard模块的方法,无法生效。
正确代码实现
首先创建SuperDiscard模块,放在app/models/concerns/super_discard.rb路径下:
require 'active_support/concern' module SuperDiscard extend ActiveSupport::Concern included do # 引入原Discard模块的所有原生功能 include Discard::Model # 统一配置默认删除标记字段 self.discard_column = :deleted_at end # 重写discard方法,支持自定义删除时间 def discard(discarded_at = DateTime.now) return false if discarded? run_callbacks(:discard) do update_attribute(self.class.discard_column, discarded_at) end end end
使用方式
直接在需要用的模型里引入即可,和预期用法完全一致:
# app/models/task.rb class Task < ApplicationRecord include SuperDiscard end
功能验证
# 默认用当前时间标记删除 task.discard # 支持传入自定义删除时间 task.discard(3.days.ago)
内容的提问来源于stack exchange,提问作者Peter Nixey
相关产品推荐
相关产品推荐

