Ruby: Active Record - Using 'exclusive_scope' in IRB
Ashwin and I have been working recently on a bit of code to make it possible to 'soft delete' some objects in our system.
We’re doing this by creating an additional column in that table called 'deleted_at_date' which we populate if a record is 'deleted'.
As we wanted the rest of the application to ignore 'deleted' records we added a default scope to it:
class Foo < ActiveRecord::Base
default_scope :conditions => "deleted_at_date is null"
end
This works fine but we wanted to be able to see the status of all the records in IRB and with the default scope 'Foo.all' no longer returns 'soft deleted' records.
Luckily Active Record provides a protected method called 'with_exclusive_scope' which we can use to get around this:
Foo.send(:with_exclusive_scope) { Foo.find(:all) }
Since it’s a protected method we can only access it in IRB by using 'send' which is a bit hacky, something David Heinemeier Hansson would refer to as syntactic vinegar.
Interestingly our first attempt to use 'with_exclusive_scope' involved writing the above code like this…
Foo.send(:with_exclusive_scope) { find(:all) }
NoMethodError: undefined method `find' for #<Object:0xb77cd94c>
from (irb):62
from /var/lib/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2143:in `with_scope'
from /var/lib/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2151:in `with_exclusive_scope'
from (irb):62:in `send'
from (irb):62
from :0
Since the main object has no method called 'find' we get an exception thrown.
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.