2012-08-29 46 views
3

我有一个简单的文件上传表单,用户应该能够从他们的机器上选择一个csv文件,然后将其保存到文件夹中。我正在尝试使用Carrierwave,我的应用程序是使用Ruby on Rails构建的。使用Carrierwave上传文件时没有路由匹配错误

当我试图保存文件时,我得到错误“无路由匹配[POST] “/客户/新”。

这里有各种组件。

/new.html。 ERB

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

<p> 
    <%= f.file_field :file %> 
</p> 
<p><%= f.submit %></p> 
<% end %> 

/models/dataload.rb

class Dataload < ActiveRecord::Base 
    attr_accessible :file_name, :request_user, :source 
    mount_uploader :file, CustomerWarrantyUploader 
end 

* /上传/ customer_warranty_uploader.rb *

class CustomerWarrantyUploader < CarrierWave::Uploader::Base 
    storage :file 
    def store_dir 
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 
    end 
    def extension_white_list 
    %w(csv) 
    end 

* customers_controller.rb(新方法;我什么也没有做这个)*

def new 
    @customer = Customer.new 

    respond_to do |format| 
     format.html # new.html.erb 
     format.json { render json: @customer } 
    end 
    end 

以下是当前的路线,为客户

resources :customers 

我不知道是什么问题,已经尝试了各种类似的做法。任何建议表示赞赏。

回答

3

原因是因为该路线确实不存在。资源创建以下路由(http://guides.rubyonrails.org/routing.html):

GET  /customers   index display a list of all photos 
GET  /customers/new  new  return an HTML form for creating a new photo 
POST /customers   create create a new photo 
GET  /customers/:id  show display a specific photo 
GET  /customers/:id/edit edit return an HTML form for editing a photo 
PUT  /customers/:id  update update a specific photo 
DELETE /customers/:id  destroy delete a specific photo 

正如你看到的,唯一的POST路径是/客户。对表单进行简单的调整就可以做到这一点。像下面这样的东西应该工作:

<%= form_for :dataload, { :url => customers_path , :html => {:multipart => true} } do |f| %> 

编辑:添加额外的信息作为用户意见的结果。

您还需要添加一些逻辑到您的控制器,以处理上传的文件。基本上,在Railscast中,他声明“网站的一部分已经建成:有一个列出了画廊的页面,其中包含指向每个画廊的链接以及显示画廊照片的页面。”。这显然包括一个新的和编辑页面,以及。该代码从他的控制器(从项目源代码 - http://media.railscasts.com/assets/episodes/sources/253-carrierwave-file-uploads.zip)是:

@gallery = Gallery.new(params[:gallery]) 

所以,当他说他的档案,他这样做是因为该模型的属性,因此,所有他不得不添加是attr_accessible :image位的模型,使控制器自动开始处理图像(因为它通过相同的参数)。由于你的参数是以不同的参数(:dataload)表示的,并且不是模型中的属性,所以使用当前的技术,您可能需要添加比他更多的代码。也许沿着线的东西:

@dataload = Dataload.create(params[:dataload]) 

甚至:

@dataload = Dataload.process_uploaded_file(params[:dataload]) 

然后,你就一个process_uploaded_file方法添加到您的Dataload脱掉你的相关客户创建逻辑...

另一件事情没有真正处理,但是,当数据出现错误时会发生什么。例如,如果上传文件中的10个条目中有2个会创建无效记录,您将如何操作(以及如何呈现错误)?

+0

太好了。没有更多的错误,我收到消息说客户已成功创建。但是,该文件不会保存在customer_warranty_uploader.rb中指定的位置。我错过了什么关于carrierwave? – analyticsPierce

+1

在控制器中,它看起来并不像你在做任何事情。你最有可能需要做类似下面的事情(以及任何其他所需的逻辑): @dataload = Dataload.create(params [:dataload]) –

+1

此外(我几乎在我原来的帖子中有这个,但删除它),您可能希望重新考虑一下您的实施。可能更希望为Dataload对象专门制作一个新的控制器,因为似乎可能会有更明显的问题分离。如果不添加客户逻辑,修复可能会更容易维护和排除故障。在这里,我假设页面上有(至少)两种形式。 –

1

我敢肯定它在你的Dataload模型,必须重定向到/customer/new但保持相同的HTTP动作,即一个POST代替GET,因此路由错误redirect_to :back

我不认为你应该有一个重定向有(重定向是控制器的领土),但无论你穿上它,你可能会需要一个303个状态码强制GET

redirect_to :back, :status => 303, alert: "your file is being processed" 

docs

如果您使用的是GET或POST其他XHR请求,重定向后的请求,则某些浏览器将按照使用原始请求方法重定向。这可能会导致不良行为,例如双重删除。要解决这个问题,您可以返回一个303 See Other status代码,它将使用GET请求进行跟踪。

+0

我从dataloads模型中删除了重定向,我仍然得到相同的错误。我试图在模型中添加一条日志消息,它从来没有跑过,我的假设是我在控制器中丢失了一些东西。思考? – analyticsPierce

+0

你能发布相关的控制器代码吗? –

+0

我在我的问题中添加了新方法的代码。这是我生成它时创建的。我知道这并没有提到在我开始使用railscast期间添加控制器代码。也许我错过了什么。我感谢您的帮助。 – analyticsPierce

0

创建通过其他控制器文件,必须使用
accepts_nested_attributes_for :dataload, allow_destroy: true
,并在你的表单中使用field_for。你也可以使用nested_form宝石

相关问题