Railsアプリケーションの起動時にクラス属性を設定したいとします。いくつかのルートを調べる必要があるので、カスタムコードを実行する前にルートをロードする必要があります。* after *ルートを実行するRailsイニシャライザはロードされていますか?
config.after_initialize do
Rails.logger.info "#{Rails.application.routes.routes.map(&:path)}"
end
しかし、それはは、「開発」環境で仕事(ルートをしません。私は、これは「テスト」環境で完璧に動作し
トラブルにフックする信頼できる場所を見つけるのを持っています空である)
今のところ、すべてのリクエストの前に私が理解するconfig.to_prepare
で同じコードを実行することで開発モードで作業しているようです。残念なことに、to_prepare
だけを使用すると、テストモードで動作しないように見えます。そのため、重複しています。
なぜテストモードでは、after_initializeの前にルートがロードされているのですが、開発モードではロードされていないのが不思議です。そして、本当に、これのための最良のフックは何ですか?すべての環境で動作する単一のフックがありますか?
*ルートをリロードするEDIT *
ムーの提案は素晴らしかったです。それは、すべての環境でafter_initialize内のルートへの一貫したアクセスを私に与えました。しかし、私の場合、to_prepareからコードを実行する必要があると思います。なぜなら、モデルにクラス属性を設定していて、各要求の前にモデルがリロードされているからです。
ここで私は何をしたのですか。
[:after_initialize, :to_prepare].each do |hook|
config.send(hook) do
User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("\n").scan(/\s\/(\w+)/).flatten.compact.uniq
end
end
これはちょっとわかりにくいようです。私はというような何かと思う:
config.after_initialize do
User.exclude_routes_from_usernames!
end
config.to_prepare do
User.exclude_routes_from_usernames!
end
をしかしUser
がRails.application.routes
を検討するための適切な場所であれば、私はよく分かりません。私はlib /でコードと同じことをすることができると思うが、それが正しいかどうかは分かりません。
もう1つの方法は、muの提案をto_prepareに適用することです。それは動作しますが、私の開発環境ではすべての要求に対してルートが再ロードされるという顕著な遅れがあるようですので、少なくとも良いとは言えませんが、少なくともDRYです。
config.to_prepare do
Rails.application.reload_routes!
User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("\n").scan(/\s\/(\w+)/).flatten.compact.uniq
end
素晴らしいアイデアを!私たちは実際に同じことをしています( 'validate_exclusion_of'で除外リストとして使われる' User.invalid_usernames'という 'class_attribute'を更新しています)。私はまだ開発モードのためにto_prepareが必要だと思う。それがなければ、最初のリクエストでうまくいきます(今は私があなたの提案を使っています)。しかし、その後、私の 'User.invalid_usernames = Set.new'はそれを壊していると思います。あなたがafter_initializeだけを使用しているように聞こえるので、周りに巧妙な方法があるのでしょうか? – poochenza
この回答は多くの助けになりましたので、私はそれを使用して終了しませんでしたが、私はそれを受け入れています(あなたは私が思うならば批判に開放!)ここで私の完全な解決策は、 //stackoverflow.com/a/8713207/1126857 – poochenza
@poochenza: 'after_initialize'を使用してリリース間に新しい競合がないことを確認しました:'/pancakes'ルートを追加して2週間後に公開すると、if誰かが生産システム上で「パンケーキ」ユーザーを作成しました。次に、ユーザー名が作成または更新されると、新しいユーザー名とルートを比較します。 –