2014-03-02 154 views
1

我有一個通過回形針上傳yml文件的問題。這是我我如何努力做到這一點:回形針上傳yml文件

在我的模型,我有:

has_attached_file :search_config 
validates_attachment_content_type :search_config, content_type: ['text/yaml', 'application/x-yaml', 'text/x-yaml', 'application/yaml', 'text/plain'] 

筆者認爲:

<%= form_for @search, :html => { :multipart => true } do |f| %> 

<fieldset> 
    <legend>Skills</legend> 
    <%= hidden_field_tag :type, 'recommendation' %> 
    <%= f.file_field :search_config %> 
    <%= f.submit 'Save', class: 'btn btn-primary' %> 
</fieldset> 

在我的控制器:

def create 
    @search = MailingSearch.new(params[:mailing_search])  
    if @search.save 
     redirect_to action: :index, notice: 'Your search was successfully created. Search results will be send via email soon.'  
    else 
     render action: :new 
    end 
end 

我得到一個錯誤,那

search_config_content_type=>["is invalid"] 

當我嘗試從控制檯文件(我使用的是相同的文件):

ms = MailingSearch.new 
ms.search_config = File.open('tmp/test.yml') 
ms.save 

它的工作原理。這裏可能有什麼問題?

+0

鑑於YML文件的解析導致去年遠程代碼執行時出現了一堆安全問題(基本上YML允許嵌入式XML允許嵌入式ruby),我會更加確信這實際上就是您必須做的。你能否恢復到像JSON這樣不太危險的格式? – Patru

+0

是的,但這是臨時功能,它只會在客戶端內部使用。 – wawka

回答

2

使用調試器檢查控制器中的params[:mailing_search]

我懷疑params[:mailing_search][:search_config].content_typeapplication/octet-stream,因爲一個.yml文件被視爲二進制文件。

由於您不允許application/octet-stream作爲有效的內容類型,這就是您遇到錯誤的原因。

當您嘗試通過控制檯時,內容類型沒有被瀏覽器覆蓋,因此它的工作原理。

在你的控制器,建設@search之前,您可以使用在PARAMS內容類型重置文件的MIME類型:

params[:mailing_search][:search_config].content_type = MIME::Types.type_for(params[:mailing_search][:search_config].original_filename).first.content_type 

這應該保留text/x-yaml的內容類型,你允許作爲文件有效。

1

您在您的示例中以完全不同的方式構建您的MailingSearch。

在你的控制器,你constantize的東西,可能是RecommendationMailingSearch,並通過將其params[:mailing_search]這確實似乎是表單的一部分,創建這個類的一個對象。

在您的手動示例中,您將實例化一個MailingSearch類型的對象並將File對象設置爲search_config

很明顯,你正在做完全不同的事情,你如何期望他們以同樣的方式行事?

也許通過改善你的問題,使對象類相互匹配和方法調用更相似,你會自己找到答案。

+0

你是對的,它可能會令人困惑。 RecommendationMailingSearch是MailingSearch(STI)的一個子類。我已經編輯了我的問題來說清楚。我嘗試了基類和子類。 – wawka