6

属性ごとにアクションを格納するために使用されるAuditクラスがあります。

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

:byと: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列を導入します。この列は、「where(deleted_at is null)」のように設定されたdefault_scopeを介して、そのモデルのすべてのクエリに対してチェックされます。パラノイアgemは、default_scopeをオンにすることで直接クエリを実行できるメソッド.with_deletedも提供し、その結果、パラノイド/ソフト削除されたオブジェクトも返します。

ただし、削除されたアイテムがあり、を使用してすべての監査済みアイテムを一覧表示しようとした場合。

Audit.all

.with_deleted呼び出しを追加する各ポリモーフィック:byおよび:onオブジェクトに対してルックアップクエリを実行するようにRailsに指示する方法がわかりません。私の推測では、railsはポリモーフィック関係のオブジェクトを次のように検索します。

eval(type).find(id)

私の場合、パラノイアジェムのdefault_scopeが適用されたオブジェクトが得られます。

Auditでself.find_by_sqlをオーバーライドしようとしましたが、うまくいきませんでした。私は先に進む前にもっと読む必要があるいくつかのArelメソッドで立ち往生しています。

次の解決策がありますが、その方法がわかりません。

  1. 多態的ルックアップを上書きします。どのように?
  2. 評価される前に生のSQLを文字列として取得し、sub / gsubWheredeleted_atがnull部分です。

これにアプローチする方法に関するありとあらゆる提案をいただければ幸いです。

4

1 に答える 1

6

これを試して:

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

これにより、レコードが本当に削除された場合は ActiveRecord::RecordNotFound エラーが発生しますが、それ以外の場合は、削除済みとしてマークされていても「on」オブジェクトが返されます。

于 2014-03-20T23:05:16.747 に答える