3 Stimmen

Rails nicht-Bild-Datei-Upload auf DB ohne Verwendung von Server-seitigen temporären Dateien?

Ich prüfe, ob es möglich ist, eine Funktion zu meiner Rails-basierten Intranetseite hinzuzufügen, die es Benutzern ermöglicht, Dateien hochzuladen.

Zwei Zwecke: Meine Benutzer sind geografisch weit verstreut, und die Verknüpfung mit Dokumenten auf dem gemeinsamen Netzwerkspeicher funktioniert nicht immer (unterschiedliche Adressen, DNS-Einträge und andere Dinge, die außerhalb meiner Kontrolle oder meines Interesses liegen), daher denke ich über eine datenbankorientierte Alternative nach. Wir haben eine Reihe von Dateien, aus denen wir die Daten auf der Client-Seite auslesen. Ich würde diese Daten gerne auf den Server übertragen können.

Ich habe mir attachment_fu, Paperclip und ein weiteres Programm (Name vergessen!) angesehen, die alle sehr bildorientiert zu sein scheinen, obwohl attachment_fu zumindest ohne eine Bildverarbeitungsbibliothek funktionieren kann, Gott sei Dank.

Das große Problem ist, dass mein Server meiner Anwendung nicht erlaubt, Dateien lokal zu schreiben, und diese Plugins scheinen alle eine Tempfile erstellen zu wollen.

Die Fragen (endlich!)

Gibt es eine vernünftige Möglichkeit, Binärdaten hochzuladen und sie im Speicher zu verarbeiten und/oder als BLOB zu speichern, ohne dass serverseitig Dateien gespeichert werden müssen?

Oder sollte ich die Idee der Dateiverteilung aufgeben und den Benutzern die zweitbeste Option geben, nämlich Textfelder zu kopieren und einzufügen, wo dies möglich ist?

(Am ehesten konnte ich bei SO folgendes finden こん was nicht wirklich hilfreich ist)

7voto

blindgaenger Punkte 1950

Sie könnten die Daten aus dem params-Objekt lesen und sie direkt in Ihr Modell schreiben.

Sie könnten zum Beispiel ein Formular wie dieses haben.

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

Dann können Sie den ursprünglichen Dateinamen und die Binärdaten leicht ermitteln.

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

Natürlich muss Ihr Modell die richtigen Spalten haben.

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

Ich hoffe, das hilft!

1voto

tvanfosson Punkte 506878

Diese HowTo for Rails enthält einen Abschnitt (am Ende der Seite), in dem beschrieben wird, wie man die Daten direkt in die Datenbank hochlädt. Dieser Abschnitt ist etwas durcheinander, aber das Wesentliche ist, dass man den Inhalt der hochgeladenen Datei einfach in das BLOB-Feld des ActiveRecord-Objekts liest und wie gewohnt speichert. Da ich nicht weiß, wie Sie die Datei in Ihrer Anwendung verwenden, kann ich Ihnen keinen Rat geben, wie Sie sie von der Datenbank aus verwenden können, obwohl es in dem HowTo auch einen Abschnitt über das Herunterladen von der DB gibt.

Möglicherweise ist es einfacher, zu prüfen, ob Sie eine Schreibberechtigung für ein einzelnes Verzeichnis auf dem Server erhalten können, z. B. für den Ordner Ihrer Webanwendung.

1voto

Orion Edwards Punkte 117361

Das große Problem ist, dass mein Server meiner Anwendung nicht erlaubt, Dateien lokal zu schreiben, und diese Plugins scheinen alle eine Tempfile erstellen zu wollen.

Ja, sonst könnten Sie die Dateien gar nicht hochladen.

Rails selbst erstellt tempfiles, wenn die hochgeladene Datei größer als 15k oder so ist.

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

Sobald Sie etwas größer als 15k hochladen, params[:upload][:file] wird ein ActionController::UploadedTempFile .

Was ist der Unterschied? Rails schreibt seine Temp-Dateien wahrscheinlich in das globale Temp-Verzeichnis (in das jeder schreiben kann), aber die Plugins versuchen wahrscheinlich, in RAILS_ROOT/tmp zu schreiben, was Ihr Server nicht zulässt. Die gute Nachricht ist, dass Sie diese Dinge einfach so konfigurieren können, dass sie ein anderes temp-Verzeichnis verwenden, damit sie ihre tempfiles schreiben können, und alles sollte funktionieren.

Zum Beispiel, Der Standard-Temp-Pfad von attachment_fu befindet sich unter rails Root. . Sie sollten sie wie folgt ändern können:

Technoweenie::AttachmentFu.tempfile_path = Dir::tmpdir

**PS: Die Dateidaten direkt aus den Parametern zu ziehen und sie in die Datenbank zu stellen, ist vielleicht immer noch die beste Lösung. Ich persönlich mag attachment_fu und seine Verwandten nicht, da sie versuchen, zu viele Dinge zu tun, aber so oder so, es ist sehr nützlich zu wissen, wie die ganze hochgeladene Datei/Temp-Datei Sache in Schienen funktioniert :-)

0voto

Mike Woodhouse Punkte 50241

Also dieser Code in meinem Controller:

  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

gibt dies für eine kleinere Datei:

b_wib.xls
application/vnd.ms-excel

b_wib.xls
ActionController::UploadedStringIO
13824

und dies für einen größeren:

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

...was genau der Beschreibung von Orion entspricht.

0voto

Kris Punkte 18038

Für alle anderen, die dies lesen, während nur das Speichern der Datei/IO in params in der Datenbank ist eine schöne Lösung (warum kompliziert Angelegenheiten) Paperclip, und ich würde vermuten, attachment_fu, sind nicht bildspezifisch. Da das Hochladen von Bildern und die Größenanpassung sehr häufig vorkommen, wird Paperclip mit einem Prozessor zur Größenanpassung von Bildern ausgeliefert, der jedoch nicht standardmäßig aktiviert ist, und Sie können leicht Ihre eigenen Prozessoren hinzufügen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X