Pre 0: I post 2 questions with almost the same intro here, but the requested/expected answers are very different
Pre: my question belongs to Rails 3.2 & plz. I don't want to discuss using default_scope
at all; I know, that there are a lot of arguments not to use it (in wrong way)
I have the 'classical' soft delete records problem that is - as I think - almost perfectly solved with a default_scope
, in my case the soft delete is for undo reasons. But I do not want to use unscope
or plain sql if I need to access a deleted record
Since my first attempt (link-after question schedule), to search the scopes already used, did not work, I found this solution that seems to work nice, but it is so easy, that I am not sure; I don't feel like a Rails "hacker"
Based on the sources and a hand full of debugging, I learned that the default_scope is resolved after all others, so the idea was just to make a dynamic default_scope
based on this:
# If you need to do more complex things with a default scope, you can alternatively # define it as a class method: # # class Article < ActiveRecord::Base # def self.default_scope # # Should return a scope, you can call 'super' here etc. # end # end
in default.rb
, I felt brave and tried following:
I have only a group of "soft delete candidates" in my models, and I want to handle them all the same way, i introduced a SoftDelRecord
- module, that I include SoftDelRecord
in all models, that are part.
The idea: "turn off default scope if a 'use all' scope was used before", so that i can use:
Toast.where(brownstate: 'fine') # default scope ON
or
Toast.include_deleted.where(brownstate: 'fine') # default scope OFF
and all other scoped variants I tried
module SoftDelRecord
def self.included base
base.extend ClassMethods
end
module ClassMethods
def default_scope
if clr_default_scope
set_clr_default_scope(false)
where('')
else
where('active = true')
end
end
def include_deleted
set_clr_default_scope('true')
where('')
end
def clr_default_scope
Thread.current["#{self}_sdr_include_deleted"]
end
def set_clr_default_scope(tf)
Thread.current["#{self}_sdr_include_deleted"]=tf
end
end
end
It's some how to easy, to believe, but all I tried works, or seems to work.
what have I overseen?
Aucun commentaire:
Enregistrer un commentaire