Reputation: 125
I have an Audit class which is used to store action, by and on attributes.
class Audit < ActiveRecord::Base
attr_accessible :activity
belongs_to :by, :polymorphic => true
belongs_to :on, :polymorphic => true
attr_accessible :by, :on
end
The polymorphic association for :by and :on is used to store any kind of objects which should be audited. Mainly because polymorphic is broken down into type and id in the schema and thus should be able to store all my model objects.
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
The problem I'm having comes from that all of the objects being audited are also using the paranoia gem. The paranoia gem introduces a deleted_at column in each models table which is checked for every query on that model through its default_scope which is set to something like "where(deleted_at is null)". The paranoia gem also provides a method .with_deleted which allows a direct query by turning of the default_scope and as a result also return objects which have beend paranoid / soft deleted.
However if I have any items that are deleted and I try to get all my Audited items listed using.
Audit.all
I can't figure out how to tell Rails to run the lookup query for each polymorphic :by and :on object adding the .with_deleted call. My guess is that rails looks up the the object of a polymorphic relation by
eval(type).find(id)
Which in my case would give me the object with the default_scope of the paranoia gem applied.
I have tried to override self.find_by_sql in Audit but with no luck. I get stuck in some Arel methods which I need to read up on more before I can move on.
I see the following solutions but I can't figure out how to do them.
Any and all suggestions on how to approach this would be greatly appreciated.
Upvotes: 7
Views: 1399
Reputation: 9857
Try this:
def on!
if on_type && on_id
on_type.constantize.with_deleted.find(on_id)
end
end
This will raise an ActiveRecord::RecordNotFound error if the record has been truly deleted, but otherwise will return the "on" object even if it is marked as deleted.
Upvotes: 7