У меня есть класс аудита, который используется для хранения действий по атрибутам и по ним.
class Audit < ActiveRecord::Base
attr_accessible :activity
belongs_to :by, :polymorphic => true
belongs_to :on, :polymorphic => true
attr_accessible :by, :on
end
Полиморфная ассоциация для :by и :on используется для хранения любых объектов, подлежащих аудиту. Главным образом потому, что полиморфный объект разбит на тип и идентификатор в схеме и, таким образом, должен иметь возможность хранить все объекты моей модели.
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
Проблема, с которой я столкнулся, связана с тем, что все проверяемые объекты также используют драгоценный камень паранойи. Драгоценный камень paranoia вводит столбец delete_at в каждую таблицу моделей, который проверяется для каждого запроса к этой модели через его default_scope, для которого установлено что-то вроде «where(deleted_at is null)». Драгоценный камень paranoia также предоставляет метод .with_deleted, который позволяет выполнять прямой запрос путем включения default_scope и в результате также возвращает объекты, которые были параноидально/мягко удалены.
Однако, если у меня есть какие-либо элементы, которые удалены, и я пытаюсь получить список всех проверенных элементов с помощью.
Audit.all
Я не могу понять, как заставить Rails запускать поисковый запрос для каждого полиморфного объекта :by и :on, добавляя вызов .with_deleted. Я предполагаю, что рельсы ищут объект полиморфного отношения с помощью
eval(type).find(id)
Что в моем случае дало бы мне объект с применением default_scope драгоценного камня паранойи.
Я пытался переопределить self.find_by_sql в аудите, но безуспешно. Я застрял в некоторых методах Arel, которые мне нужно прочитать больше, прежде чем я смогу двигаться дальше.
Я вижу следующие решения, но я не могу понять, как их сделать.
- Перезаписать полиморфный поиск. Как?
- Получите необработанный SQL в виде строки, прежде чем он будет оценен, и вставьте в sub/gsub часть, где удаленный_ат является нулевой частью.
Буду очень признателен за любые предложения о том, как подойти к этому.