2011-09-22 7 views
6

私のwebappはセッションデータを暗号化する必要があります。私がセットアップしたもの:Rails 3.1:Webアプリケーション(レールサーバー/ユニコン/ etc)のイニシャライザを実行する方法

config/initializers/encryptor.rb: 

require 'openssl' 
require 'myapp/encryptor' 

MyApp::Encryptor.config[ :random_key ] = OpenSSL::Random.random_bytes(128) 
Session.delete_all 

app/models/session.rb: 

require 'attr_encrypted' 

class Session < ActiveRecord::Base 
    attr_accessible :session_id, :data 
    attr_encryptor :data, :key => proc { MyApp::Encryptor.config[ :random_key ] }, :marshal => true 

    # Rest of model stuff 
end 

すべてがうまく動作し、セッションデータを保護します。問題は次のとおりです。カスタムレイクタスクを実行すると、イニシャライザが読み込まれ、すべてのセッションがクリアされます。良くない!

私は自分のイニシャライザに入れて、Webアプリケーションの初期化のためだけに実行することができますか?または、私は自分のイニシャライザでレイクタスクを実行しないようにするために何を入れることができますか?

更新:これまでに行ったことは、.rakeファイルにMYAPP_IN_RAKE = true unless defined? MYAPP_IN_RAKEを追加することです。私のイニシャライザでは次のようにします:

unless defined?(MYAPP_IN_RAKE) && MYAPP_IN_RAKE 
    # Web only initialization 
end 

と思われます。しかし、私は他の提案に開放しています。

+0

これは、将来的には他の方法であなたを噛まないように責任を負うようです。サーバーが再起動されると、(意図された動作であると思われる)すべてのセッションを失うことになりますが、あまりにも多くのメモリを使用して自動取得され、要求が長時間実行されているなどがあります。 –

+0

欠点を理解するが、それはそれが価値があると思う。アプリケーションを再起動してセッションをリセットする:受け入れ可能。メモリが多すぎるか、リクエストが長すぎますか?ユニコーンでは、これらの状況はワーカープロセスでのみ発生する必要があります。そして 'preload_app = true'を設定しているので、初期化はマスターでのみ起こります。したがって、ユニコンは再初期化を行わずにワーカーを復活させることができます。 – sbutler

+0

[Rails 3の初期化子が\ rails server \のみで実行され、\ rails generate \ 'などは使用できません](http://stackoverflow.com/questions/8660019/rails-3-initializers-that- run-on-rails-server-and-not-rails-generate-e) – davmac

答えて

8

次のようなの `config/application.rb」で、アプリケーションに変更を行う場合があります

module MyApp 
    def self.rake? 
    [email protected] 
    end 

    def self.rake=(value) 
    @rake = !!value 
    end 

次に、あなたのRakefileにあなたはこの追加したい:

MyApp.rake = true 

それはうれしいですが後でそれらを変更または再定義することを好むことがあるので、定数ではなくメソッドを使用します。さらに、ルート名前空間を汚染しません。ここで

はサンプルconfig/initializers/rake_environment_test.rbスクリプトです:

if (MyApp.rake?) 
    puts "In rake" 
else 
    puts "Not in rake" 
end 

Rakefileのプログラマブルな性質はあなたに大きな柔軟性を与えます。

+0

OK、これが好きです。私は定義されていない限り、設定者を '@rake = !! valueに変更しましたか? @ rake'を実行して一度しか設定されていないことを確認します。次に、environment.rbにMyApp.rake = falseを追加しました。合理的な音ですか? – sbutler

+0

なぜあなたはそれを一度しか設定することを心配しませんか?重複セットを無視するよりも、少なくとも警告を出したり、例外をスローして問題の原因を突き止めることができます。 – tadman

+0

私は、Webアプリケーションコードとして実行している途中で、何とかRakefileがロードされることに懸念していると思います。私は対称的に考えています:rakeとしてwebapp環境がロードされているので、webappとしてrakeがロードされるケースも処理する必要があります。 – sbutler

2

別の回避策はあります:

unless ENV["RAILS_ENV"].nil? || ENV["RAILS_ENV"] == 'test' 

あなたは熊手を起動すると、あなたのENV [ "RAILS_ENV"]はゼロになります。 'test'のテストは、rspecを使用するときに実行されないようにすることです。

Rails.envを使用すると分かりますが、初期化されていない場合は「開発」を返します。

http://apidock.com/rails/Rails/env/class

# File railties/lib/rails.rb, line 55 
def env 
    @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] 
    || ENV["RACK_ENV"] || "development") 
end 
+0

ありがとう!ちょうど私が必要なもの! –

関連する問題