Rails で ReadOnly なデータベースを扱う場合のいろいろ
Rails で書き込みをしたくない参照専用の DB を扱った際に、間違えて更新してしまわないために変更した箇所を備忘録代わりにメモ。
バージョンは 3.2.13 です。
ActiveRecord
使っているのは Rails 3 なんですが、なんとなく Rails 4 の concerns っぽくしてみました。
まずは Model の concerns ディレクトリを作成。
$ mkdir -p app/models/concerns
作成したディレクトリを config/application.rb の autoload_paths に追加して自動ロードされるように設定します。
config.autoload_paths += %W(#{config.root}/app/models/concerns)
以下のような Module を作成。
- app/models/concerns/readonlyable.rb
読み取り専用にしたい Model で作成した Module を include します。
# -*- coding: utf-8 -*- class ReadOnlyModel < ActiveRecord::Base include Readonlyable ・ ・ ・
これで Model は OK のはず。
rails console で save や delete を呼ぶと ActiveRecord::ReadOnlyRecord が飛んできます。
参考サイト
以下を参考にさせて頂きました。
LunaTear: RailsでReadonlyなmodel
http://lunatear.net/archives/001089.html
Read only models in ActiveRecord - toamitkumar's Code Blog
http://toamitkumar.com/blog/2009/05/27/read-only-models-in-activerecord/
Test
rake で Test を実行した際に db:test:prepare が走り、テスト用 DB が Drop されてしまいます。
今回はテスト用 DB も Drop したくなかったので、以下のようにして db:test:prepare を無効にしました。
Rails アプリケーションの直下にある Rakefile を開き、load_tasks より前の辺りに以下を追記します。
Rake::TaskManager.class_eval do def remove_task(task_name) @tasks.delete(task_name.to_s) end end
次に、lib/tasks/db/test.rake ファイルを作成します。
% mkdir lib/tasks/db
% vim lib/tasks/db/test.rake
以下の内容を記述します。
Rake.application.remove_task 'db:test:prepare' namespace :db do namespace :test do task :prepare do |t| # rewrite the task to not do anything you don't want puts "Override db:test:prepare to NOT run drop database" end end end
これで bundle exec rake を実行しても db:test:prepare が実行されないため、テスト用データベースに入れておいた値が消えなくなります。
参考
以下を参考にさせて頂きました。
kennyjのブログ(仮): spec実行時にdb:test:prepareを呼び出したくない。
http://kennyj-jp.blogspot.jp/2011/09/specdbtestprepare.html
ruby on rails - How to prevent Rake test to call task db:test:prepare - Stack Overflow
http://stackoverflow.com/questions/1097845/how-to-prevent-rake-test-to-call-task-dbtestprepare/1101325#1101325
Capistrano
Capistrano も deploy:cold 実行時などに deploy:migrate が呼ばれてマイグレーションが実行されます。
オペミスなどでこれらのタスクを間違えて実行してしまう可能性も排除したかったので、タスク自体を無効化しました。
deploy.rb に以下を追記します。
namespace(:deploy) do [:cold, :migrate, :migrations, ].each { |t| task(t) { puts "#{t} is disabled." } } end
定義後に cap -T を実行してみるとタスクが表示されなくなり、無効化されていることが分かります。
参考
CakePHP2アプリケーションをCapistranoでデプロイする | Ryuzee.com
http://www.ryuzee.com/contents/blog/6119
これだけやっておけば大丈夫かな。