2016-08-14 19 views
0

這個問題發生在對蝦PDF生成器在我的Rails應用程序,在那裏我有以下行:爲什麼Carrierwave和資產管道似乎以不同的方式解釋config.asset_host?

image open(@user.avatar.url) 

在測試中這條線開始了與以下錯誤而失敗:

No such file or directory @ rb_sysopen - /images/fallback/default.png 

頭像是一個Carrierwave上傳,使用默認的圖像(see here

def default_url(*args) 
    ActionController::Base.helpers.asset_path("images/fallback/default.png") 
end 

這似乎像它會是一個簡單的辦法 - 定義資產主辦test.rb

config.asset_host = Rails.root.join('app', 'assets').to_s 

但當時我所有的JS啓用功能測試開始失敗

Capybara::Poltergeist::JavascriptError: 
One or more errors were raised in the Javascript code on the page. 
ReferenceError: Can't find variable: SomeVariable 

因爲路徑下使用兩個assets,例如構建

...app/assets/assets/jquery..

我清楚這樣做違背了做事的方式Rails的一些「非常規」。所以我想知道這裏的約定是什麼。

一種解決方案是將我從test.rb定義資產文件夾的位置移動到上傳器。

#config/environments/test.rb 
config.asset_host = Rails.root.join('app').to_s 
#app/uploaders/avatar.eb 
def default_url(*args) 
    ActionController::Base.helpers.asset_path("assets/images/fallback/default.png") 
end 

但是這將意味着helpers.asset_path其實也不是調用的資源路徑,但應用程序文件夾,這又似乎違背Rails約定。

我原以爲本地主機會工作

config.asset_host = "http://localhost" 

但同樣JS文件失敗

我敢肯定,我俯瞰的東西在這裏很明顯。感謝指向正確方向的指針。

回答

1

我認爲這歸結爲路徑和URL的各種含義的混合。

首先關閉asset_host用於您希望將資產文件從不同服務器提供給您的應用程序(即從cdn)。如果您查看asset_path的來源,則首先計算資產的路徑,然後預先託管主機。這將創建一個瀏覽器將稍後嘗試提取網址,所以前面加上像/Users/andy/some_app的路徑沒有意義

將其設置爲http://localhost不起作用,因爲它假定默認http端口,而水豚上運行你的應用程序一個隨機的端口。您不應該在測試環境中設置asset_host

從瀏覽器的角度來看,移動到載波上,avatar.url也提供了URL(在你的情況下只是路徑部分) - 它被設計成嵌入在img標籤中。另一方面,open方法對瀏覽器和服務器一無所知,只想要一個到本地文件系統上的文件的路徑。

如果你想要一個本地文件系統路徑,那麼你需要avatar.path方法。據我所知,目前還沒有default_url的路徑等價的,所以你需要做好準備,它返回零(和與路徑替換到您的後備代替)

#config/environments/test.rb 
# do not set config.asset_host 

#pdf_generator.rb 
image open(@user.avatar.path) 

#app/uploaders/avatar.rb 
def path(*args) 
    if model.avatar? 
    super 
    else 
    "#{Rails.root}/app/assets/images/fallback/" + ["default_",version_name, ".png"].compact.join('') 
    end 
end 
+0

感謝@frederick,這是一個很好的解釋和清理了很多問題。但是'avatar.path'本質上返回的是沒有主機的'avatar.url',對嗎?在這種情況下,'/ images/fallback/default.png',這是'avatar.url'在我的測試中返回的內容,並且不適用於'open'方法。應該「開放」迴應「avatar.path」? –

+0

比較這些值並查看它們返回的內容 - 不應該是同一件事。此外,後備圖像是一個特殊情況 - 我的東西路徑將只返回零。 –

+0

正確,回退返回'nil'。如果設置了圖片,'avatar.path'將返回'avatars/filename.jpg',而'avatar.url'返回'http:// path/to/app/avatars/filename.jpg'。所以我需要一個方法,'如果avatar.path.nil?'返回'/ app/assets/images/fallback/default.png'。或者我誤解了? –

相關問題