Как я могу предотвратить запись ActiveRecord в БД? - PullRequest
1 голос
/ 21 сентября 2011

У меня есть несколько особый вариант использования, где я хотел бы создать метод, который принимает блок, так что все, что происходит внутри этого блока, не записывается в БД.

Очевидный ответ - использовать транзакции следующим образом:

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)

1 Ответ

0 голосов
/ 21 сентября 2011

Это может быть один из способов сделать это:

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 / классы / SQLite / Database.html # M000071

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...