如何防止ActiveRecord写入数据库?

我有一个特殊的用例,我想创建一个接受块的方法,这样在该块内发生的任何事情都不会写入数据库。

显而易见的答案是使用这样的交易:

def no_db ActiveRecord::Base.transaction do yield raise ActiveRecord::Rollback end end 

但麻烦的是,如果我的no_db方法在另一个事务块中使用,那么我将在嵌套事务的情况下使用。 这里的缺点是嵌套事务只有MySQL支持,我需要支持PG,但更重要的是SQLite(用于测试)。 (我知道PG是通过保存点支持的,性能有多可靠?)。

这种方法的另一个问题是它看起来效率非常低,将数据写入数据库,然后将它们回滚。 如果我可以做这样的事情会更好:

 def no_db_2 # ActiveRecord::Base.turn_off_database yield # ActiveRecord::Base.turn_on_database end 

有这样的方法吗? 或者类似于我正在寻找的方法? 我认为它需要相当低的水平..

(Rails版本是3.0.5,但如果有一个优雅的Rails 3.1解决方案,我会很高兴)

这可能是一种方法:

 class Book < ActiveRecord::Base # the usual stuff end # Seems like a hack but you'll get the # transaction behavior this way... class ReadOnly < ActiveRecord::Base establish_connection "#{Rails.env}_readonly" end 

我认为这......

 ReadOnly.transaction do Book.delete_all end 

......应该失败。

最后,添加另一个连接到config / database.yml

 development: username: fullaccess development_readonly: username: readonly 

一个缺点是sqlite3-ruby驱动程序中缺少对只读模式的支持。 你会注意到mode参数根据文档还没有做任何事情。 http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html#M000071