Rails загрузка файлов без изображения в БД без использования временных файлов на стороне сервера? - PullRequest
3 голосов
/ 15 ноября 2008

Я изучаю возможность добавления функции на мой сайт в интрасети на основе Rails, которая позволяет пользователям загружать файлы.

Два назначения: Мои пользователи широко распространены географически, и ссылки на документы в общем сетевом хранилище не всегда работают (разные адреса, записи DNS и другие вещи вне моего контроля или интереса), поэтому я думаю о предоставлении альтернативы, ориентированной на базу данных. У нас есть ряд файлов, из которых мы анализируем данные на стороне клиента. Я бы предпочел иметь возможность отправить это на сервер.

Я смотрел на attachment_fu, Paperclip и еще один (забыл имя!), Которые кажутся очень ориентированными на изображение, хотя по крайней мере attachment_fu может работать без библиотеки обработки изображений, слава богу.

Большая проблема в том, что мой сервер не позволяет моему приложению записывать файлы локально, и все эти плагины, похоже, хотят создать Tempfile.

Вопросы (наконец-то!)

Есть ли разумный способ загрузить двоичные данные и обработать их в памяти и / или сохранить их как большой двоичный объект без сохранения файлов на стороне сервера?

Или я должен отказаться от идеи распространения файлов и предоставить пользователям второй лучший вариант копирования и вставки текстовых полей, где это возможно?

(Самым близким, что я мог найти на SO, было это , которое на самом деле не помогает)

Ответы [ 5 ]

7 голосов
/ 16 ноября 2008

Вы можете прочитать данные из объекта params и записать их прямо в вашу модель.

Например, у вас может быть такая форма.

<% form_for :upload, :url => {:action=>:upload}, :html=>{:multipart=>true} do |f| %>
  <%= f.file_field :file %>
  <%= f.submit 'Upload' %>
<% end %>

Тогда вы можете легко получить исходное имя файла и двоичные данные.

class TestController < ApplicationController

  def upload 
    file_param = params[:upload][:file]
    filename = file_param.original_filename
    filedata = file_param.read

    @data = UploadedFile.create(:name => filename, :data => filedata)

    render :text => "created #{@data.id}"
  end

end

Конечно, ваша модель должна иметь правильные столбцы.

class CreateUploadedFiles < ActiveRecord::Migration
  def self.up
    create_table :uploaded_files do |t|
      t.string :name
      t.binary :data
      t.timestamps
    end
  end

  def self.down
    drop_table :uploaded_files
  end
end

Надеюсь, это поможет!

1 голос
/ 17 ноября 2008

Большая проблема в том, что мой сервер не позволяет моему приложению записывать файлы локально, и все эти плагины, похоже, хотят создать Tempfile.

Да, это так, иначе вы не сможете загрузить файлы вообще.

Rails сам создает временные файлы, если загруженный файл больше 15k или около того.

<%= f.file_field :file %>
....
file_param = params[:upload][:file]

Как только вы загрузите что-то больше 15 КБ, params[:upload][:file] станет ActionController::UploadedTempFile.

Какая разница? Rails, вероятно, записывает свои временные файлы в глобальный временный каталог (в который каждый может писать), но плагины, вероятно, пытаются записать в RAILS_ROOT / tmp, который запрещен вашим сервером. Хорошей новостью является то, что вы можете просто настроить эти вещи для использования другого временного каталога, чтобы они могли писать свои временные файлы, и все должно работать.

Например, временный путь по умолчанию attachment_fu находится в корневом каталоге rails. . Вы должны быть в состоянии изменить это так:

Technoweenie::AttachmentFu.tempfile_path = Dir::tmpdir

** PS: лучший способ - это извлечь данные файла прямо из параметров и поместить их в базу данных. Мне лично не нравится attachment_fu, и это похоже, поскольку они пытаются сделать слишком много вещей, но в любом случае очень полезно знать о том, как весь загруженный файл / временный файл работает в rails: -)

1 голос
/ 15 ноября 2008

Это HowTo для Rails включает в себя раздел (в конце страницы) о том, как загрузить непосредственно в базу данных. Этот раздел в некотором роде запутан, но суть в том, что вы просто читаете содержимое загруженного файла в поле BLOB объекта ActiveRecord и сохраняете как обычно. Поскольку я не знаю, как вы используете файл внутри своего приложения, я не могу дать никаких советов о том, как использовать его из базы данных, хотя в HowTo есть также раздел о загрузке из БД.

Может быть проще увидеть, можно ли получить разрешение на запись в один каталог, возможно, в папку вашего веб-приложения, на сервере.

0 голосов
/ 05 августа 2010

Для тех, кто читает это, просто сохраняя File / IO в параметрах в базе данных, является хорошим решением (почему все так сложно) Paperclip, и я подозреваю, что attachment_fu, не привязаны к конкретному изображению. Поскольку загрузка изображений и изменение их размеров очень распространены, Paperclip поставляется в комплекте с процессором для изменения размера изображений, но он не включен по умолчанию, и вы можете легко добавлять свои собственные процессоры.

0 голосов
/ 20 ноября 2008

Итак, этот код в моем контроллере:

  def upload
    file_content = params[:upload][:file]
    render :text => [
      [:original_path, :content_type, :local_path, :path, :original_filename].collect {|m| file_content.send(m)},
      file_content.class, 
      file_content.size.to_s].flatten.join("<br/>")
  end

дает это для меньшего файла:

b_wib.xls
application/vnd.ms-excel


b_wib.xls
ActionController::UploadedStringIO
13824

и это для большего:

a_wib.xls
application/vnd.ms-excel
/tmp/CGI.10029.1
/tmp/CGI.10029.1
a_wib.xls
ActionController::UploadedTempfile
27648

... что в точности соответствует описанию Ориона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...