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

时间:2012-11-25 21:16:44

标签: ruby-on-rails-3 polymorphic-associations soft-delete

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

class Audit < ActiveRecord::Base
  attr_accessible :activity
  belongs_to :by, :polymorphic => true
  belongs_to :on, :polymorphic => true
  attr_accessible :by, :on
end

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

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

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

Audit.all

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

查找多态关系的对象
eval(type).find(id)

在我的情况下,我会使用所应用的偏执宝石的default_scope给我一个对象。

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

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

  1. 覆盖多态查找。怎么样?
  2. 在评估之前将原始SQL作为字符串获取,并将sub / gsub作为Where deleted_at为null的部分。
  3. 非常感谢任何有关如何处理这一问题的建议。

1 个答案:

答案 0 :(得分:4)

试试这个:

def on!
  if on_type && on_id
    on_type.constantize.with_deleted.find(on_id)
  end
end

如果记录已被真正删除,这将引发ActiveRecord :: RecordNotFound错误,否则将返回&#34; on&#34;对象,即使它被标记为已删除。