我怎样才能prevent的ActiveRecord写入到数据库

我怎样才能prevent的ActiveRecord写入到数据库

本文介绍了我怎样才能prevent的ActiveRecord写入到数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

但麻烦的是,如果我no_db方法用于其它事务块里面,然后我将定义在嵌套事务的情况。这里的缺点是嵌套事务只能由MySQL的支持,我需要为PG支持,但更重要的是SQLite的(用于测试)。 (据我所知,PG通过保存点支持,如何可靠的是什么?性能影响?)。

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的版本是3.0.5,但我会很高兴,如果有适合于Rails 3.1的一流解决方案)

(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:

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

我会认为这...

I would think that this...

ReadOnly.transaction do
  Book.delete_all
end

......应该失败。

...should fail.

最后,添加另一个连接到配置/ database.yml中

Finally, add another connection to config/database.yml

development:
  username: fullaccess

development_readonly:
  username: readonly

一个缺点是缺乏支持在sqlite3的,红宝石的驱动程序只读模式。你会发现,根据文档的模式参数没有做任何事情。 http://sqlite-ruby.rubyforge.org/classes/SQLite/Database html的#M000071

这篇关于我怎样才能prevent的ActiveRecord写入到数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 19:08