I have a somewhat special use case, where I’d like to create a method that accepts a block, such that anything that happens inside that block is not written to the DB.
The obvious answer is to use transactions like so:
def no_db
ActiveRecord::Base.transaction do
yield
raise ActiveRecord::Rollback
end
end
But the trouble is that if my no_db method is used inside of another transaction block, then I’ll ned up in the case of nested transactions. The drawback here is that nested transactions are only supported by MySQL, and I need support for PG, but more importantly SQLite (for tests). (I understand that PG is supported via savepoints, how reliable is that? performance hit?).
The other problem with this type of approach is that it seems really inefficient, writing things to a DB, and then rolling them back. It would be better if I could do something like this:
def no_db_2
# ActiveRecord::Base.turn_off_database
yield
# ActiveRecord::Base.turn_on_database
end
Is there such a method? Or a similar approach to what I’m looking for? I think it needs to be fairly low level..
(Rails version is 3.0.5, but I would be happy if there were an elegant solution for Rails 3.1)
This might be one way to do it:
I would think that this…
…should fail.
Finally, add another connection to config/database.yml
One downside is the lack of support for a read-only mode in the sqlite3-ruby driver. You’ll notice that the mode parameter doesn’t do anything yet according to the documentation. http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html#M000071