8

Rails 3アプリを更新してRails 3.1を使用していて、その一部として新しいアセットパイプラインを使用しています。これまでのところ、私は解決できない厄介な問題とは別のものをすべて手に入れました。サブURIにデプロイするときにRails 3.1のプリコンパイルされた資産が壊れた

アプリケーションとそのすべてのアセットは開発には問題ありませんが、運用時にはPassenger(http://the-host/sub-uri/)を使用してサブURIにデプロイされます。この問題は、アセットがデプロイ時に事前にコンパイルされており、CSSのファイル(.css.scssファイル)の1つがsass-rails宝石のimage-urlヘルパーを使用していることが問題です。私の.css.scssファイルで

:事前コンパイルプロセスの間に、パスがプリコンパイルされたCSSファイルにハードコーディングされているので、サブURIはのアカウントを取られていない

body { background-image: image-url("bg.png"); } 

結果を中それが正常に動作させるためにどうあるべきか

body { background-image: url(/assets/bg.png); } 

body { background-image: url(/sub-uri/assets/bg.png); } 
ファイルをコンパイル

このシナリオはあまりにも多くのことを求めていますか?もしそうなら、私は古い非資産パイプラインの方法に戻って、publicから自分の画像とCSSを提供しなければならないでしょう。しかし、それは考えられて解決すべきであった何かのように思えます...?解決策が見当たりませんか?


編集1:は、私は1つが期待するようerb solutionを使用する代わりに、同じ結果が得られることに注意してください。


編集2:ブノワ・ギャレットさんのコメント

に応じていいえ、問題がconfig.assets.prefixとは関係ありません。私はそれを設定しようとしました(/assetsのデフォルトではなく、になっています)、間違ったことが判明しました。この設定はすでにRailsアプリのルートであってサーバーではないようです。それを削除してデフォルトに戻すと、原因となった奇妙な問題がすべて修正されました(そして、多くの資産がすべて/sub-uri/sub-uri/assetsになりました - それはすべて非常に奇妙でした)。唯一の問題は、image-urlのヘルパーと友人が、事前コンパイル時にサブURIを取得しないことです。言うまでもなく、これはあらかじめコンパイルされているので、Passengerで実行されているときにはこのように設定されることを知ることができないため、論理的です。私の質問は、これを通知して、プリコンパイルされた結果の正しいパスになる方法です。確かにそれができる場合。

現時点での回避策は、CSSのiamgeをurl(../images/bg.png)のように参照して、パイプライン化されていないpublic/imagesの場所に配置することです。フィンガープリンティングやパイプラインが提供するすべてのメリットがないため、ほとんど理想的ではありません。

+0

これを試しましたか? http://stackoverflow.com/questions/7295744/how-to-deploy-rails-3-1-app-in-a-subdirectory –

+0

アプリ自体はうまく配置されています(RailsBaseURIメソッドは乗客のように使用します) docsが推奨します)。 'image_tag'などを使ったイメージのように、実行中のアプリケーションからリンクされているすべてのアセットは問題ありません。唯一の問題は、CSS内から参照される画像です。資産の事前コンパイル時にサブURIについてはわかりません。それがあれば解決策が必要なのです。 –

+0

あなたの問題は、 'image-uri'ヘルパーが' config.assets.prefix'を拾わないということですか? –

答えて

4

最後に、いくつかの回避策/解決策を試しました。

1)https://github.com/rails/sass-rails/issues/17から、これはSass-Railで修正される可能性があります。私は猿のパッチを当てたヘルパーです。上のリンクの提案されたパッチの行に沿って自分自身を作りましょう。資産プリコンパイル行に必要な環境変数をdeploy.rbに設定するだけです。

私のすべての猿のパッチは、単一のファイルconfig/initializers/gem_patches.rbで行います。あなたが.erb拡張子を持つようにスタイルシートを変更し、CSSで画像を埋め込むことが大丈夫です、とurl(<%= asset_data_uri "bg.png" %>)image-url("bg.png")を交換して任意のせずに動作するかどう代わり

module Sass 
    module Rails 
    module Helpers 
     protected 
     def public_path(asset, kind) 
     path = options[:custom][:resolver].public_path(asset, kind.pluralize) 
     path = ENV['PRODUCTION_URI'] + path if ENV['PRODUCTION_URI'] 
     path 
     end 
    end 
    end 
end 

2):このファイルでは、私は、この方法をパッチを適用しましたサスレールを変更する必要があります。 asset-data-uriは純粋なSass関数として存在しないため、Railsヘルパーasset_data_uriを使用する必要があります。

+0

2番目のポイントでうれしい叫び - それはうまくいくだろうと思ったことは一度もありません。確かに望ましいものではありませんが、有効な回避策です。ポイント1については、 'deploy.rb'で変数の設定を明確にすることはできますか? –

+0

私はちょうどあなたが何を意味するかを試しました。あなたはdeploy.rbファイルからプリコンパイルタスクを手動で実行していますか?私はCapfileに 'load 'deploy/assets''を追加して、提供されたものを使用しています - 環境変数設定を置く必要がある' deploy.rb'にはどこにも明白なものはありません。私はそれを設定する他の場所を見つけることができると確信しています。最悪の場合でさえ、あなたは私に目を向ける問題を与えてくれました。私はそれが今のところ答えだと思います。ありがとう:) –

+0

正確に。私の 'deploy.rb'では、' after "deploy:update_code"タスクにアセットがプリコンパイルされています。 RAILS_ENV = production PRODUCTION_URI = '/ myapp' "'そして、私の猿パッチされたhelpers.rbの中で 'ENV ['PRODUCTION_URI']'をピックアップして、 。 –

0

少し掘り下げた後、私は問題を発見しました。問題はRails、特にSprockets :: Helpers :: RailsHelper :: AssetPaths#compute_public_pathにあります。 Sprockets :: Helpers :: RailsHelper :: AssetPathsはActionView :: AssetPathsから継承し、いくつかのメソッドをオーバーライドします。 compute_public_pathがSass :: Rails :: Resolver#public_pathメソッドを介して呼び出されると、sass-railsメソッドが呼び出され、railsスプロケットヘルパーはアセットを解決するタスクを取得します。 Sprockets :: Helpers :: RailsHelper :: AssetPaths#compute_public_pathは、ActionView :: AssetPaths#compute_public_pathであるsuperに向いています。このメソッドにはhas_requestの条件がありますか? rewrite_relative_url_rootに下図のように:

def compute_public_path(source, dir, ext = nil, include_host = true, protocol = nil) 
    ... 
    source = rewrite_relative_url_root(source, relative_url_root) if has_request? 
    ... 
end 

def relative_url_root 
    config = controller.config if controller.respond_to?(:config) 
    config ||= config.action_controller if config.action_controller.present? 
    config ||= config 
    config.relative_url_root 
end 

あなたはそれが存在し、相対URLのルートを解決するために、コントローラ変数からそれを誘導する能力であることを要求に依存しているrewrite_relative_url_rootの内部を見れば。問題は、スプロケットがこれらの資産を解決するときにコントローラが存在せず、従って要求もないことである。

上記の解決策は開発モードでは機能しませんでした。最新のRailsで

module Sass 
    module Rails 
    module Helpers 
     protected 
     def public_path(asset, kind) 
     resolver = options[:custom][:resolver] 
     asset_paths = resolver.context.asset_paths 
     path = resolver.public_path(asset, kind.pluralize) 
     if !asset_paths.send(:has_request?) && ENV['RAILS_RELATIVE_URL_ROOT'] 
      path = ENV['RAILS_RELATIVE_URL_ROOT'] + path 
     end 
     path 
     end 
    end 
    end 
end 
+0

これは本質的に他の答えと同じ修正だと思っていますが、少し違う? (たぶん少しばかりではなく、他のアプローチが私に何か問題を引き起こしたのではない...) –

+0

https://github.com/rails/rails/pull/2977 –

2

あなたはこれが何をされ、それは

を動作させるために、今、別のモジュールにパッチを適用サルに必要な3.1.3:ここで私はそれが今のところ動作させるために使用しています解決策があります

desc "precompile the assets" 
namespace :assets do 
    task :precompile_assets do 
    run "cd #{release_path} && rm -rf public/assets/* && RAILS_ENV=production bundle exec rake assets:precompile RAILS_RELATIVE_URL_ROOT='/my_sub_uri'" 
    end 
end 
before "deploy:symlink", "assets:precompile_assets" 
+3

ありがとう。 Rails 3.2ではパッチは必要ないと分かっていました。 "bundle exec rake assets:precompile RAILS_RELATIVE_URL_ROOT = '/ my_sub_uri'" 'それが動作します –

+0

ありがとう@SiweiShen、capistranoのためdeploy.rbの中でdeploy前に実行するタスクを追加しました:assets:プリコンパイル、 'set: asset_env、 "#{asset_env} RAILS_RELATIVE_URL_ROOT =/my_sub_uri" ' – Cam

2

私はRailsの3.1.3を使用していますし、suする展開:私は

module Sprockets 
    module Helpers 
    module RailsHelper 

     def asset_path(source, options = {}) 
     source = source.logical_path if source.respond_to?(:logical_path) 
     path = asset_paths.compute_public_path(source, asset_prefix, options.merge(:body => true)) 
     path = options[:body] ? "#{path}?body=1" : path 
     if !asset_paths.send(:has_request?) 
      path = ENV['RAILS_RELATIVE_URL_ROOT'] + path if ENV['RAILS_RELATIVE_URL_ROOT'] 
     end 
     path 
     end 

    end 
    end 
end 

そして、私が持っている私のdeploy.rbにしましたb-URIは正常に終了しました。 私は何も猿にパッチを当てていません。

このセットアップの重要な問題は、よりよく解説されましたhere。ご覧のように、このソリューションはRails 3.2に適用され、3.1.4にバックポートされることはありません。

しかし、自分のセットアップで動作するRails 3.1.3を使用してソリューションに来ました。(私は時間のために私を苦しめ、問題を解決するために貢献しようと、何の専門家だ...)

environment.rbに:

#at top: 
ENV['RAILS_RELATIVE_URL_ROOT'] = '/rais' 

はこれを試してみてください製造。RB:

config.assets.prefix = ENV['RAILS_RELATIVE_URL_ROOT'] ? ENV['RAILS_RELATIVE_URL_ROOT'] + '/assets' : '/assets' 

routes.rbを:あなたが見ることができるように

Rais::Application.routes.draw do 
     scope ENV['RAILS_RELATIVE_URL_ROOT'] || '/' do #see config/environment.rb 
      <<resources here>> 
     end 
    end 

、私はその後ないapplication.rb で、production.rb内assets.prefix入れているあなたは:

rake assets:clear 
rake assets:precompile 

よりも、コンソールでテスト:

RAILS_ENV=production rails console 

結果:

foo = ActionView::Base.new 
foo.stylesheet_link_tag 'application' 
=> "<link href=\"/rais/assets/layout.css?body=1\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/rais/assets/application.css?body=1\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />" 
foo.image_tag('arrow-up.png') 
=> "<img alt=\"Arrow-up\" src=\"/rais/assets/arrow-up-ca314ad9b991768ad2b9dcbeeb8760de.png\" />" 
関連する問題