Поддержка двоичных потоков Rails
В ближайшее время я начну проект, который потребует поддержки двоичных файлов большого размера. Я хотел бы использовать Ruby on Rails для webapp, но я заинтересован в поддержке BLOB. В моем опыте работы с другими языками, фреймворками и базами данных BLOB часто пропускаются и, следовательно, имеют плохую, сложную и/или багги функциональность.
Соответствует ли RoR spport BLOB? Есть ли какие-либо ошибки, которые ползут, как только вы уже привязаны к Rails?
BTW: Я хочу использовать PostgreSQL и/или MySQL в качестве базы данных. Очевидно, что поддержка BLOB в базовой базе данных важна. На данный момент я хочу избежать фокусировки на возможностях DB BLOB; Меня больше интересует, как реагирует сам Rails. В идеале Rails должен скрывать детали базы данных от меня, и поэтому я должен иметь возможность переключаться с одного на другой. Если это не так (например, есть проблема с использованием Rails с конкретным БД), то, пожалуйста, упомяните об этом.
UPDATE: Кроме того, я говорю не только об ActiveRecord. Мне нужно обработать двоичные файлы на стороне HTTP (эффективно загружать файлы). Это означает получение доступа к соответствующим HTTP-заголовкам и потокам через Rails. Я обновил заголовок и описание вопроса, чтобы отразить это.
Ответы
Ответ 1
+1 для attachment_fu
Я использую attachment_fu в одном из моих приложений и ДОЛЖЕН хранить файлы в БД (по досадным причинам, выходящим за рамки этого конвоя).
(одна?) сложная вещь, связанная с BLOB, которую я обнаружил, заключается в том, что вам нужен отдельный путь кода для отправки данных пользователю - вы не можете просто вставить путь к файловой системе, как вы если бы это был простой файл Джейн.
например. если вы храните информацию об аватаре, вы не можете просто сделать:
<%= image_tag @youruser.avatar.path %>
вам нужно написать некоторую логику оболочки и использовать send_data, например. (ниже JUST пример w/attachment_fu, на практике вам нужно DRY это)
send_data(@youruser.avatar.current_data, :type => @youruser.avatar.content_type, :filename => @youruser.avatar.filename, :disposition => 'inline' )
К сожалению, насколько я знаю, attachment_fu (у меня нет последней версии) не делает для вас умной упаковки - вы должны написать ее самостоятельно.
P.S.
Увидев ваш вопрос, редактируйте - Attachment_fu обрабатывает все, что раздражает, о чем вы упоминаете, - о необходимости знать пути к файлам и все это дерьмо - ЗА ИСКЛЮЧЕНИЕМ одной маленькой проблемы при хранении в БД. Попробуйте; это стандарт для приложений rails. Если вы настаиваете на повторном создании колеса, исходный код для attachment_fu должен также документировать большую часть gotchas!
Ответ 2
Что касается потоковой передачи, вы можете сделать все это в (по крайней мере, в памяти). На стороне загрузки параметры файла в формах абстрагируются как объекты ввода-вывода, которые вы можете прочитать; на стороне загрузки, посмотрите на форму render :text =>
, которая принимает аргумент Proc:
render :content_type => 'application/octet-stream', :text => Proc.new {
|response, output|
# do something that reads data and writes it to output
}
Если ваши файлы находятся в файлах на диске, все же вышеупомянутые решения, безусловно, будут работать лучше.
Ответ 3
Вы можете использовать тип :binary
в своей миграции ActiveRecord, а также ограничить максимальный размер:
class BlobTest < ActiveRecord::Migration
def self.up
create_table :files do |t|
t.column :file_data, :binary, :limit => 1.megabyte
end
end
end
ActiveRecord предоставляет содержимое BLOB (или CLOB) как строку Ruby.
Ответ 4
Я думаю, что ваш лучший выбор - плагин attachment_fu:
http://github.com/technoweenie/attachment_fu/tree/master
UPDATE: нашел дополнительную информацию здесь http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/a81beffb93708bb3
Ответ 5
Посмотрите плагин, x_send_file.
"Плагин XSendFile предоставляет простой интерфейс для отправки файлов через HTTP-заголовок X-Sendfile. Это позволяет вашему веб-серверу обслуживать файл непосредственно с диска, а не передавать его через ваш Rails-процесс. Это быстрее и экономит много памяти, если вы используете Mongrel. Не каждый веб-сервер поддерживает этот заголовок. YMMV."
Я не уверен, что он можно использовать с Blobs, это может быть только файл в файловой системе. Но вам, вероятно, нужно что-то, что не связывает веб-сервер с потоком больших фрагментов данных.