在Rails 3中如何临时上传文件?

8
我正在为我的网站创建CSV上传功能。我想要上传文件,解析它,然后处理掉它。
我知道可以使用Paperclip上传和保存文件,但那似乎有点过头了。
我只需要解析上传的文件并且不保存它。在Rails 3中我该如何做呢?
注意:我更喜欢手动上传而不使用外部gem,这样我就可以学习处理的工作方式,但是任何建议都受欢迎。
谢谢!

http://guides.rubyonrails.org/form_helpers.html#uploading-files - klochner
http://easyrails.herokuapp.com/blogs/5/upload-file-in-rails-without-model-creation - vajapravin
这需要你手动返回并删除这个“临时”文件吗?我正在使用你选择的方法。 - E.E.33
3个回答

8

在表单中使用file_field助手,然后在控制器中使用File.WriteFile.read保存文件。

例如View:

<%= form_for @ticket do |f| %>
  <%= f.file_field :uploaded_file %>
<% end %>

控制器

def upload
  uploaded = params[:ticket][:uploaded_file]
  File.open(<insert_filename_here>, 'w') do |file|
    file.write(uploaded.read)
  end
end

编辑:我刚看到@klochner的评论,那个链接说得和我说的差不多,所以请参考这个链接:RubyOnRails Guides: Uploading Files


如果在保存图片或PDF文件时出现ASCII警告,请将类型从w更改为wb,其中wb代表写入二进制。这应该可以解决您的问题。 - sergserg

1
将此代码粘贴到您的模型中。
  def parse_file
   File.open(uploaded/file/path, 'w') do |f|  # Feed path that user gives in some way
   ## Parse here
   end
  end

这是视图中的内容

  <%=form_for @page, :multipart => true do |f|%>

    <ul><li><%= f.label :file%></li>
    <li><%= f.file_field :uploaded_file%></li></ul>

  <%end%>

如果这样可以,请告诉我。如果失败了,请想办法在parse_file方法中提供uploaded_file的路径(能够确保成功的方法是将文件位置存储在数据库中并从那里获取,但这不是正确的做法)。否则,我猜应该可以工作。


非常感谢您抽出时间回答 :) - Yuval Karmi

1

完整示例

以上传包含联系人信息的导入文件为例。您不需要存储此导入文件,只需处理并丢弃它。

路由

routes.rb

resources :contacts do 
  collection do
    get 'import/new', to: :new_import  # import_new_contacts_path

    post :import, on: :collection      # import_contacts_path
  end
end

表单

views/contacts/new_import.html.erb

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

  <%= f.file_field :import_file %>

<% end %>

控制器

controllers/contacts_controller.rb

def new_import
end

def import
  begin
    Contact.import( params[:contacts][:import_file] ) 

    flash[:success] = "<strong>Contacts Imported!</strong>"

    redirect_to contacts_path

  rescue => exception 
    flash[:error] = "There was a problem importing that contacts file.<br>
      <strong>#{exception.message}</strong><br>"

    redirect_to import_new_contacts_path
  end
end

联系模型

models/contact.rb

def import import_file 
  File.foreach( import_file.path ).with_index do |line, index| 

    # Process each line.

    # For any errors just raise an error with a message like this: 
    #   raise "There is a duplicate in row #{index + 1}."
    # And your controller will redirect the user and show a flash message.

  end
end

@MartinPohorský 没有理由不行。试一试并告诉我们结果。 - Joshua Pinter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接