通过Rails 3中的多态关系获取偏执狂删除的对象

zma*_*lex 5 soft-delete polymorphic-associations ruby-on-rails-3

我有一个Audit类,用于存储按属性的动作.

class Audit < ActiveRecord::Base
  attr_accessible :activity
  belongs_to :by, :polymorphic => true
  belongs_to :on, :polymorphic => true
  attr_accessible :by, :on
end
Run Code Online (Sandbox Code Playgroud)

for和:on的多态关联用于存储应审计的任何类型的对象.主要是因为多态在模式中被分解为类型和id,因此应该能够存储我的所有模型对象.

  create_table "audits", :force => true do |t|
    t.string   "activity"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
    t.integer  "on_id"
    t.string   "on_type"
    t.integer  "by_id"
    t.string   "by_type"
  end
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是所有被审计的对象都使用了偏执狂宝石.偏执宝石在每个模型表中引入了deleted_at列,通过其default_scope检查该模型上的每个查询,default_scope设置为"where(deleted_at is null)".偏执宝石还提供了一种方法.with_deleted,它允许通过转动default_scope进行直接查询,因此也返回具有偏执/软删除的对象.

但是,如果我有任何已删除的项目,我会尝试使用列出的所有审核项目.

Audit.all
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚如何告诉Rails为每个多态的运行查询查询:by和:on对象添加.with_deleted调用.我的猜测是,rails通过查找多态关系的对象

eval(type).find(id)
Run Code Online (Sandbox Code Playgroud)

在我的情况下会给我一个应用了偏执宝石的default_scope的对象.

我试图在审计中覆盖self.find_by_sql,但没有运气.在我继续前进之前,我遇到了一些我需要阅读的Arel方法.

我看到以下解决方案,但我无法弄清楚如何做到这些.

  1. 覆盖多态查找.怎么样?
  2. 在评估之前将原始SQL作为字符串获取,并将where deleted_at为null部分的子/ gsub.

任何和所有关于如何处理这个问题的建议将不胜感激.

Mat*_*lly 5

尝试这个:

def on!
  if on_type && on_id
    on_type.constantize.with_deleted.find(on_id)
  end
end
Run Code Online (Sandbox Code Playgroud)

如果记录已被真正删除,这将引发ActiveRecord :: RecordNotFound错误,否则,即使将其标记为已删除,也将返回“ on”对象。