2011-09-15 20 views
31

私はHerokuのCedarスタックにRails 3.1アプリケーションを導入しています。 Heroku Cedar and Rails 3.1を使用すると、資産をローカルでコンパイルすることができ、Herokuが(「スラッグコンパイル」中に)プッシュするときにそれらをコンパイルしたり、アプリケーションの実行中にジャストインタイムでコンパイルすることができます。私は中間のオプションを実行し、Herokuに資産をプリコンパイルさせたいと思います。Herokuのアセットをプリコンパイルするときにデータベース全体をスキップする方法

Herokuがassets:precompileタスクを実行するときに、アプリケーションがデータベースに接続しようとしているのに、スラッグコンパイルのその段階でデータベースが利用できないため、エラーは"could not connect to server"となります。現時点では、データベース接続の不足が予想され、避けられません。データベースの接続がアセットのプリコンパイルには重要ではないため、過去に移動する方法を探しています。

データベースに接続しようとしているアプリケーションの一部がDeviseです。 routes.rbには、ユーザモデルを見たいと考えているdevise_for :usersという行があります。

私は、devise_forをスタブし、それを資産の前提条件にするレイクタスクを書くことができます:プリコンパイル。私はそれが私の問題を解決するだろうと思うが、私はには、この問題がHeroku上で使用できるより普遍的なソリューションを探しています。

そこには何かがありますか、ルートとアセットのパスを生成するのに十分なほどアプリを実行している間にデータベース接続エラーを消すものは何ですか?

起動時にデータを読み書きする必要がある場合は、スタブすることはできませんが、自動的にすべてのActiveRecordモデルを偽装できますか?

答えて

3

編集:この回答は最新ではなく、もはや機能しません.- fringdの回答を参照してください。

普遍的なスタブではありませんが、この特定の問題を解決するためのチェックが追加されました。 Githubのissuefixを参照してください。 RAILS_ASSETS_PRECOMPILE環境設定を提供することによって、ルートを構築することをスキップする必要があります

+0

すごいです!私にこれを警告してくれてありがとう。 Herokuのチケットに、この環境変数を設定しておく必要があることを追加しました。 – jasongarber

+2

申し訳ありませんが、私はこの修正がDevise and Railsから実際に取り戻されたと考えています。ホセ・ヴァリムは問題を回避しようとするために少しでも華麗なフットワークをしましたが、彼はそれがあまりにもこの時点でDevise HEADとRails 3-1の安定したブランチでまだ壊れている場合、私はあなたの開発モデルの作業と、どの特定のメソッドが問題を引き起こしているかを特定しようとすること以外は何もしないと思います。 –

+1

更新いただきありがとうございます。 Herokuは、彼らが別の角度から問題に取り組んでいると私に言った。私たちはそれが揺れるのを待たなければならないと思う。自分の状況を回避する方法があります。 – jasongarber

1

これを 'lib/tasks/assets.rake'に貼り付け、実際に成功するようにプリコンパイルすることができました。これは、環境を必要とするために実際にデータベースにアクセスしない限り有効です。明らかにActiveRecordでは助けにならないでしょうが、すべてのmongoidベースのアプリケーションでうまくいくはずです。

task 'assets:precompile' => 'assets:stub_mongoid' 

task 'assets:stub_mongoid' do 
    def Mongoid.load!(*args) 
    true 
    end 
end 
5

私の場合、問題はactiverecordをlib/active_record/railtie.rb:92に呼び出すアクティブレコードです。これによりオブザーバとそれぞれのモデルがロードされます。 has_and_belongs_to_manyはdbに接続します。

ENV["RAILS_ASSETS_PRECOMPILE"]が存在する場合、このメソッドを無効にします。これは、Bradleyにリンクされている修正プログラムでdeviseが使用します。

EDIT:だからこのスニペットは、私のためにそれを修正:

namespace :assets do 
    # Prepend the assets:precompile_prepare task to assets:precompile. 
    task :precompile => :precompile_prepare 

    # This task will be called before assets:precompile to optimize the 
    # compilation, i.e. to prevent any DB calls. 
    task 'precompile_prepare' do 
    # Without this assets:precompile will call itself again with this var set. 
    # This basically speeds things up. 
    ENV['RAILS_GROUPS'] = 'assets' 

    # Devise uses this flag to prevent connecting to the db. 
    ENV['RAILS_ASSETS_PRECOMPILE'] = 'true' 

    # Prevent loading observers which will load the models which in turn may hit 
    # the DB. 
    module ActiveModel::Observing::ClassMethods 
     def instantiate_observers; end 
    end 

    # Prevent route drawing because certain gems might get called which will hit 
    # the DB. 
    class ActionDispatch::Routing::RouteSet 
     def draw; end 
    end 
    end 
end 
+0

ありがとう、この問題を徹底的に徹底的に解消してきた! – aaronrussell

+0

私のためにも治療をしました。ありがとう。 – Ivan

0

Spork.trap_methodも早いロードプロセスでモデルを呼び出しroutes_for考案者の問題に興味深いソリューションです。解決策はAFAIKに直接適用することはできませんが、同じ種類の問題を解決しているので、誰かにインスピレーションを与えるかもしれません。

Spork.trap_method

46

設定/アプリケーションにこれを追加します。RB

config.assets.initialize_on_precompile=false             

はこれを追い詰めるために私にしばらく時間がかかった...設定/環境/ *に追加するRBが

UPDATE動作しませんでした:それは、レール4

では動作しませんが
+1

メインのSassファイルに@import( 'compass')を入れて(コンパスのすべてのミックスインを取得するために)これが動作しないようです。 'インポートするファイルが見つからないか、読み取れない:コンパス'というエラーが出ます。 require 'compass'はapplication.rbファイルに含まれていますが、環境がロードされていない場合はロードされません。誰かがこれを回避する方法を知っていますか? – Marc

+0

それは私のために働いた、私はレールでモンゴイドを使用している3.1.3 –

+3

これはまた、アセットパイプラインに関する公式のレールガイドで引用されています:http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets –

1

Herokuは、プリコンパイル中に環境(つまりDBも)にアクセスできるように非公式のフラグを追加しました。スイッチをオンにして、資産のプリコンパイル時のDB依存関係はもはや問題にはなりません。このフラグが正式に利用可能かどうか、または単に新しいデフォルトになるかどうかはわかりません。

+0

ありがとう、Nico。私はこの昨日、友人を助けていました。私はこれが多くの人々を助けると思う。乾杯! – jasongarber

+0

このフラグを自分で有効にできるようになりました。私はそれについての答えを投稿します。 – kch

13

ここで、labsフラグを使用すると、コンパイル時にランタイム環境を利用できるようになります。つまり、アプリケーションがDATABASE_URLデータベースに正常に接続できるようになります。 /config/initializers/precompile.rbとして以下を追加します

:Railsのための

$ heroku labs:enable user-env-compile --app your-app-name 
+0

このページのすべての提案のうち、これが私に役立つ唯一のものです。 FYI:Rails 3.2.0.rc2 –

+0

最後に、実用的な解決策です。私はHerokuがRailsトラブルシューティングのページでこの機能を文書化したいと思っています。 – lupefiasco

+0

これが答えです! dbに無条件でアクセスしようとする宝石があれば(これは?active_adminなど)、これが実際に動作する唯一の解決策です。ありがとう、トン。 – trisweb

3

回避策(4.2エッジ):

$ heroku plugins:install http://github.com/heroku/heroku-labs.git 

が、その後user-env-compile labs featureを有効にします。

まずあなたがlabsプラグインをインストールする必要があります。

module Precompile 

    # Public: ignore the following block during rake assets:precompile 
    def self.ignore 

    unless ARGV.any? { |e| e == 'assets:precompile' } 
     yield 
    else 
     line = caller.first 
     puts "Ignoring line '#{line}' during precompile" 
    end 

    end 

end 

とは、このようなあなたのroutes.rbでそれを使用します。

Precompile.ignore { ActiveAdmin.routes(self) } 
0

は、私がコメントするのに十分な評判が不足しているので、ここで別の答えです。

それは@ fringdのトップクラスの答えはRailsの4で動作しないというのは本当だ私は、しかし、この技術が機能することがわかっています

https://iprog.com/posting/2013/07/errors-when-precompiling-assets-in-rails-4-0

私はそうのようなBASH変数を並び替え、けれども:

~$ RAILS_ENV=production DATABASE_URL=postgresql://user:[email protected]/dbname bundle exec rake assets:precompile 

ところで、これはDockerイメージを構築する必要がある場合には非常に便利です。その行をDockerfileに入れて、DBを別のコンテナに入れて、アプリケーションコンテナが起動するたびにアセットをあらかじめコンパイルする必要はありません!

+0

は私のために働かなかった。 – EightyEight

0

無効にAR:

config = Rails.application.config 
def config.database_configuration 
    {} 
end 

ar = ActiveRecord::Base 
def ar.establish_connection 
end 
関連する問題