8

पर तैनाती करते समय रेल 3.1 में टूटी हुई प्रीकंपील्ड संपत्तियां मैं रेल 3.1 का उपयोग करने के लिए रेल 3 ऐप अपडेट करने की प्रक्रिया में हूं और इसके हिस्से के रूप में, नई संपत्ति पाइपलाइन का उपयोग कर रहा हूं। अब तक, मुझे एक भी परेशान करने वाली समस्या से अलग सब कुछ मिल गया है जिसे मैं हल नहीं कर सकता।उप-यूआरआई

आवेदन और इसकी सभी संपत्तियां विकास में ठीक काम करती हैं, लेकिन उत्पादन में इसे यात्री (http://the-host/sub-uri/) का उपयोग करके उप-यूआरआई में तैनात किया जाता है। इसके साथ समस्या यह है कि संपत्ति तैनाती के दौरान पूर्व-संकलित होती है और मेरी सीएसएस में से एक (अच्छी तरह से, यह .css.scss फ़ाइल है) फाइलें मणि से image-url सहायक का उपयोग कर रही हैं। में

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

परिणाम: चूंकि पूर्व संकलन की प्रक्रिया के दौरान, रास्तों precompiled सीएसएस फ़ाइल में हार्ड-कोडेड कर रहे हैं, सब-uri के कारण नहीं लिया जाता है:

मेरी .css.scss फ़ाइल में संकलित application-<md5-hash-here>.css फ़ाइल:

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

क्या यह इसे सही ढंग से काम करने के लिए किया जाना चाहिए:

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

क्या यह परिदृश्य सिर्फ इतना पूछ रहा है? यदि ऐसा है, तो मुझे पुराने गैर-परिसंपत्ति-पाइपलाइन तरीके पर वापस जाना होगा और केवल public से मेरी छवियों और सीएसएस की सेवा करनी होगी। हालांकि ऐसा कुछ ऐसा लगता है जिसे सोचा और हल किया जाना चाहिए था ...? क्या मुझे समाधान याद आ रहा है?


संपादित करें 1: मैं नोट करना चाहिए कि erb solution उपयोग करने के बजाय एक ही परिणाम पैदावार, के रूप में एक उम्मीद होती है।


संपादित करें 2: बेनोइट अटारी की टिप्पणी के जवाब में

नहीं है, समस्या config.assets.prefix से संबंधित नहीं है। मैंने इसे सेट करने की कोशिश की (/sub-uri/assets/assets के डिफ़ॉल्ट के बजाय) लेकिन यह पता चला कि यह गलत काम था - ऐसा लगता है कि यह सेटिंग पहले से ही रेल ऐप की जड़ के संबंध में है, सर्वर नहीं। इसे हटाने (और इस प्रकार डिफ़ॉल्ट पर लौटने) ने सभी अजीब मुद्दों को ठीक कर दिया है (और वहां कई थे, सभी संपत्ति /sub-uri/sub-uri/assets में समाप्त हुई - यह सब बहुत अजीब था)। एकमात्र समस्या यह है कि image-url सहायक और मित्र उप-यूआरआई नहीं लेते हैं जब वे पूर्व-संकलित होते हैं। कहने की जरूरत नहीं है, यह पहले से संकलित होने के बाद तार्किक है, यह संभवतः यह नहीं जान सका कि जब यात्री के तहत यह चल रहा है, तो इसे इस तरह से कॉन्फ़िगर किया जाएगा। मेरा सवाल यह है कि इसे कैसे सूचित किया जाए और इस प्रकार प्रीकंपिल्ड परिणाम में सही पथों को समाप्त किया जाए। अगर वास्तव में यह किया जा सकता है।

मेरा वर्तमान कामकाज सीएसएस में इस तरह के आईएजी को संदर्भित करना है: url(../images/bg.png) और इसे गैर-पाइपलाइन public/images स्थान पर रखें। मुश्किल से आदर्श क्योंकि यह फिंगरप्रिंटिंग और पाइपलाइन प्रदान करता है जो सब कुछ से लाभ नहीं होता है।

+0

क्या आपने इसे आजमाया? http://stackoverflow.com/questions/7295744/how-to-deploy-rails-3-1-app-in-a-subdirectory –

+0

ऐप स्वयं को ठीक से तैनात किया गया है (यह रेलवेबेसरी विधि का उपयोग करता है क्योंकि यह यात्रियों के रूप में है दस्तावेज़ अनुशंसा)। 'Image_tag' का उपयोग कर छवियों जैसे चल रहे एप्लिकेशन के भीतर से जुड़ी सभी संपत्तियां ठीक हैं। सीएसएस के भीतर से संदर्भित छवियों की एकमात्र समस्या है - यह संपत्ति के पूर्व-संकलन के समय उप-यूआरआई के बारे में नहीं जानता है। यह है कि यदि कोई है तो मुझे समाधान की आवश्यकता है। –

+0

तो आपकी समस्या यह है कि 'image-uri' सहायक' config.assets.prefix' नहीं उठाता है? –

उत्तर

4

अंत में मैंने कुछ कामकाज/समाधान तैयार किए हैं।

1) https://github.com/rails/sass-rails/issues/17 से ऐसा लगता है कि यह सैस रेल में तय हो सकता है। मेरे पास बंदर-पैच वाले हेल्पर्स हैं। ऊपर दिए गए लिंक में प्रस्तावित पैच की लाइनों के साथ स्वयं को आरआरबी करें।मैंने बस deploy.rb में एसेट प्रीकंपाइल लाइन में आवश्यक पर्यावरण चर सेट किया है।

मैं अपने सभी बंदर को एक फ़ाइल में config/initializers/gem_patches.rb में पैचिंग करता हूं। इस फाइल में मैं के रूप में इस पद्धति का समझौता:

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) वैकल्पिक रूप से यदि आप सीएसएस में छवियों एम्बेड करने के लिए ठीक है, स्टाइलशीट बदल रहा है एक .erb विस्तार करने के लिए, और जगह image-url("bg.png")url(<%= asset_data_uri "bg.png" %>) के साथ किसी भी बिना काम करेंगे सास रेल बदलने की जरूरत है। asset-data-uri शुद्ध सास फ़ंक्शन के रूप में मौजूद नहीं है, इसलिए आपको रेल हेल्पर asset_data_uri का उपयोग करना होगा।

+0

दूसरे बिंदु पर अच्छा चिल्लाओ - यह काम करेगा और ऐसा कुछ है जिसे मैंने कभी नहीं माना। वांछनीय से निश्चित रूप से कम, लेकिन एक वैध कामकाज। बिंदु 1 के लिए, क्या आप 'deploy.rb' में चर की सेटिंग को स्पष्ट कर सकते हैं? –

+0

मैंने अभी आपके काम का क्या काम किया है ... आप मैन्युअल रूप से precompile कार्य को अपने deploy.rb फ़ाइल से चला रहे हैं, है ना? मैं अपने कैप्फ़ाइल में 'लोड' तैनाती/संपत्ति 'जोड़कर आपूर्ति किए गए एक का उपयोग कर रहा हूं - इसलिए' deploy.rb' में कहीं भी स्पष्ट नहीं है जहां मुझे पर्यावरण परिवर्तनीय सेटिंग रखना चाहिए। मुझे यकीन है कि मैं इसे सेट करने के लिए कहीं और पा सकता हूं। यहां तक ​​कि सबसे बुरी स्थिति में, आपने मुझे नजर रखने के लिए एक मुद्दा दिया है, सबसे अच्छा मुझे लगता है कि यह अभी जवाब है। धन्यवाद :) –

+0

बिल्कुल। मेरे 'deploy.rb' में मेरे पास 'बाद" तैनाती में अद्यतन प्रीकंपाइल है: update_code "' task। मैं 'रन' करता हूं सीडी # {रिलीज_पैथ}; बंडल निष्पादन रेक संपत्तियां: प्रीकंपाइल RAILS_ENV = उत्पादन PRODUCTION_URI = '/ myapp' "और फिर मेरे बंदर-पैच किए गए हेल्पर्स में। आरबी मैं बस' ENV ['PRODUCTION_URI'] उठाता हूं ' । –

0

कुछ खोदने के बाद, मुझे यह समस्या मिली है। मुद्दा रेल में है, विशेष रूप से स्प्राकेट्स :: हेल्पर्स :: रेलशेल्पर :: एसेटपैथ # compute_public_path। स्प्राकेट्स :: हेल्पर्स :: रेलहेल्पर :: एसेटपैथ एक्शन व्यू :: एसेटपैथ से विरासत में आता है और कई तरीकों को ओवरराइड करता है। जब compute_public_path को Sass :: Rails :: Resolver # public_path विधि के माध्यम से बुलाया जाता है, तो sass-rails है, रेल स्पॉकेट सहायक संपत्ति को हल करने के कार्य को उठाता है। Sprockets :: हेल्पर्स :: RailsHelper :: AssetPaths # compute_public_path सुपर पर डिफर्स करता है जो एक्शन व्यू :: एसेटपैथ # compute_public_path है। इस विधि में 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 

आप rewrite_relative_url_root के आंतरिक यह एक अनुरोध पर निर्भर करता है वर्तमान और आदेश रिश्तेदार यूआरएल जड़ को हल करने में नियंत्रक चर से यह प्राप्त करने की क्षमता होने के लिए देखें। मुद्दा यह है कि जब sprockets एसएएस के लिए इन संपत्तियों को हल करता है तो इसमें नियंत्रक मौजूद नहीं होता है और इसलिए कोई अनुरोध नहीं होता है।

उपरोक्त समाधान मेरे लिए विकास मोड में काम नहीं करता है।

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: यहाँ समाधान है कि मैं अब के लिए काम करने के लिए उपयोग कर रहा हूँ है मैं

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 में मेरे पास है:

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

धन्यवाद। और मैंने पाया कि रेल 3.2 में हमें पैच की आवश्यकता नहीं है। बस आदेश 'बंडल निष्पादन रेक संपत्तियों को चलाएं: प्रीकंपाइल RAILS_RELATIVE_URL_ROOT ='/my_sub_uri '"' और यह काम करता है –

+0

धन्यवाद @ सिवेइशेन, कैपिस्ट्रानो के लिए मैंने तैनाती से पहले चलाने के लिए तैनाती.आरबी में एक कार्य जोड़ा: संपत्ति: प्रीकंपाइल, जो' सेट: asset_env, "# {property_env} RAILS_RELATIVE_URL_ROOT =/my_sub_uri" ' – Cam

2

मैं रेल 3.1.3 का उपयोग कर रहा है और एक सु करने के लिए की तैनाती बी-यूआरआई सफलतापूर्वक। मैंने कुछ बंदर-पैच नहीं किया है।

इस सेटअप के साथ मुख्य समस्याएं here पर बेहतर चर्चा की गई हैं। जैसा कि आप देख सकते हैं, समाधान रेल 3.2 पर लागू किया गया था और कभी वापस 3.1.4 तक नहीं भेजा गया था।

लेकिन, मैं रेलवे 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 

आप देख सकते हैं, मैं production.rb अंदर assets.prefix रख दिया है, application.rb में नहीं उसके बाद आप कार्य करें:

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\" />"