我通过回形针上传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 :(得分:2)
使用调试器检查控制器中的params[:mailing_search]
。
我怀疑params[:mailing_search][:search_config].content_type
将是application/octet-stream
,因为.yml文件被视为二进制文件。
由于您不允许application/octet-stream
作为有效的内容类型,因此您就会收到错误。
当您尝试通过控制台时,浏览器不会覆盖内容类型,因此它可以正常工作。
在您的控制器中,在构建@search
之前,您可以使用以下命令将参数中的内容类型重置为文件的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 :(得分:1)
在您的示例中,您确实以完全不同的方式构建了MailingSearch。
在你的控制器中,你可以对RecommendationMailingSearch
的内容进行实例化,并通过传递<{1>}来创建该类的对象,而不似乎是你表单的一部分。
在您的手动示例中,您实例化params[:mailing_search]
类型的对象,并将MailingSearch
对象设置为File
。
很明显,你做了完全不同的事情,你怎么期望他们以同样的方式行事?
也许通过改进你的问题,使对象类相互匹配,方法调用更相似,你就可以自己找到答案。