Подтвердить что ты не робот

Загрузка файла без активации

Как вы обрабатываете загрузку файлов в рельсе, не привязывая их к активной записи?
Я просто хочу записать файлы на диск.

Спасибо,

4b9b3361

Ответ 1

Если я правильно понимаю, что вам нужно, самым простым примером будет следующее:

Контроллер:

  class UploadController < ApplicationController
  def new

  end

  def create
    name = params[:upload][:file].original_filename
    path = File.join("public", "images", "upload", name)
    File.open(path, "wb") { |f| f.write(params[:upload][:file].read) }
    flash[:notice] = "File uploaded"
    redirect_to "/upload/new"
  end
end

Вид:

<% flash.each do |key, msg| %>
    <%= content_tag :div, msg, :class => [key, " message"], :id => "notice_#{key}" %>
<% end %>
<% form_tag '/upload/create', { :multipart => true } do %>
    <p>
    <%= file_field_tag 'upload[file]' %>
    </p>
    <p>
        <%= submit_tag "Upload" %>
    </p>
<% end %>

Это позволит вам загружать любой файл без каких-либо проверок или проверок, которые, на мой взгляд, не так полезны.

Если бы я сделал это сам, я бы использовал что-то вроде validatable gem или без табличного камня, только tableless больше не поддерживается. Эти драгоценные камни позволят вам проверить, что вы загружаете, чтобы сделать его более разумным.

Ответ 2

Вы можете просто переместить временный файл на путь судьбы, используя FileUtils

tmp = params[:my_file_field].tempfile
destiny_file = File.join('public', 'uploads', params[:my_file_field].original_filename)
FileUtils.move tmp.path, destiny_file

Ответ 3

Документация Tempfile показывает пример, эквивалентный коду Rytis, который отлично работает в большинстве случаев. Но когда вы вызываете tempfile.read, Ruby считывает весь файл в виде одного фрагмента в память, что является субоптимальным.

Однако FileUtils предоставляет метод copy_stream, а IO, по крайней мере, в Ruby 2.0, предоставляет copy_stream реализация, которая обрабатывает прямое обращение к пути к файлу (FileUtils.copy_stream требует файлов с похожими файлами с обеих сторон, или так говорят документы).

В моем случае я инициировал большую загрузку нескольких файлов через AJAX и хотел не читать весь файл в памяти Ruby перед записью на диск.

В приведенном ниже примере params[:files] - это Array экземпляров ActionDispatch::Http::UploadedFile, а local_filepath - строка, указывающая на несуществующий файл в существующем каталоге. Для краткости я предполагаю, что я загружаю только один файл:

IO.copy_stream(params[:files][0].tempfile, local_filepath)

В экземпляре ActionDispatch::Http::UploadedFile есть поле .tempfile, которое является обычным экземпляром Tempfile.

Я не уверен, что Ruby все еще не читает весь файл в памяти - я ничего не тестировал, но это намного более возможно, чем с синтаксисом localfile.write(tempfile.read).

tl; dr: IO.copy_stream(your_tempfile, your_disk_filepath) является более кратким, если не быстрее.

Ответ 4

Вы можете попробовать использовать плагин Rails Attachment_fu для обработки загрузки файлов. Он позволяет сохранять загрузки в файловую систему вместо базы данных.