Datei Download von Link des Carrierwave-Dokumentanhangs

8

Ich versuche einen einfachen Link zu erstellen, der, wenn er angeklickt wird, den Download eines Dokuments auslöst, das einer bestimmten Ressource zugeordnet ist. Ich habe ein Ressourcenmodell und in diesem Modell gibt es eine Spalte namens "Dokument". Ich kann das Dokument erfolgreich inline anzeigen, wenn auf den Link geklickt wird, aber ich würde es lieber herunterladen. Ich habe über Content-Typen und send_file gelesen, aber ich war nicht in der Lage, dies komplett zusammenzufügen, um zu funktionieren.

Hier ist der Code, den ich glaube, den ich für den Link verwenden muss:
<%= link_to 'Download File', :action => "download_file" %>

Dies löst einen Fehler aus:
ActiveRecord :: RecordNotFound in ResourcesController # show Ressource mit id = download_file

konnte nicht gefunden werden

Wenn ich den Link zu diesem ändern, öffnet es die Datei im Browser:
<%= link_to 'Open file', resource.document_url, :target => "_blank" %>

In meinem ResourcesController habe ich diese Methode definiert:

%Vor%

Ich habe eine Route in routes.rb wie folgt eingerichtet:

%Vor%

Aufgrund dieses Fehlers scheint meine Methode download_file in ResourcesController nicht in der Lage zu sein, die ID des Ressourcendatensatzes zu ermitteln, mit dem das Dokument verknüpft ist.

Ich renne: Schienen 3.2.11 Trägerwelle 0.8.0 Ruby 1.9.3-p194

Ich würde einen Einblick in diese Sache schätzen. Ich habe eine Reihe von Artikeln durchsucht und konnte kein einfaches Tutorial finden. Danke.

    
acoustic_north 10.03.2013, 19:52
quelle

1 Antwort

13

Ich konnte das herausfinden. Ich werde versuchen zu erklären, wie ich dieses Problem behoben habe.

Die download_file-Methode wurde korrekt im ResourcesController gefunden, aber ich habe nicht die richtigen Variablennamen verwendet. Hier ist die richtige Methodendefinition für meine Zwecke:

%Vor%

In meinem Fall habe ich einen Datensatz in der Variable @ resource zurückgegeben, der ein Dokument zugeordnet ist (wieder verwende ich Carrierwave). Das erste Argument, das send_file benötigt, ist der Pfad (siehe API für send_file ). Diese Pfadinformationen werden von @ resource.document.path bereitgestellt.

send_file nimmt eine Reihe anderer Argumente, die scheinbar optional sind, weil ich nur drei davon benötigt habe. Weitere Informationen zu den anderen Argumenten finden Sie in der API-Dokumentation.

Einer von denen, die den Fehler für mich geworfen haben, war der Typ :. Ich habe es die Variable "@ resource.file.content_type" übergeben, aber es war offensichtlich auf der Suche nach einem Literal. Sobald ich es application / pdf übergeben habe, hat es funktioniert. Ohne dies explizit festzulegen, wird der Datei, die heruntergeladen wird, keine Dateierweiterung hinzugefügt. In jedem Fall könnte dieses Dokument für meine App eine Vielzahl verschiedener MIME-Typen sein, von PDF über Word bis MP4. Also ich bin mir nicht sicher, wie man mehrere angibt.

Das wirklich wichtige Argument für meine Zwecke (zum Herunterladen statt zur Anzeige im Browser) ist die: disposition, die auf 'attachment' gesetzt werden muss, im Gegensatz zu 'inline'.

Das andere Argument: url_based_filename wird anscheinend verwendet, um den Namen der Datei aus der URL zu bestimmen. Da ich den Dateinamen nicht zur Verfügung stelle, ist dies vielleicht die einzige Möglichkeit für mich, die Datei herunterzuladen, aber ich bin mir nicht sicher.

Ich musste auch das link_to-Tag zu diesem ändern:
<%= link_to 'Download File', :action => 'download_file', :id => resource.id %>

Beachten Sie, dass die Angabe des ID-Symbols mit der ID der aktuellen Ressource die spezifischen Informationen lieferte, die zur Identifizierung der betreffenden Ressource erforderlich sind.

Ich hoffe, dass dies jemand anderem hilft. Dies muss für alle anderen sehr offensichtlich sein, da ich beim Herunterladen von Dateien keine grundlegenden Anleitungen gefunden habe. Ich lerne immer noch sehr viel.

UPDATE: Ich musste damit herumspielen, um das gewünschte Verhalten zu bekommen. Hier ist die neue Methode, die funktioniert:

%Vor%

Mit diesen Änderungen muss ich nicht mehr den: Typ einstellen. Die Einstellung ": url_based_filename = & gt; true" führte die Benennung der Datei nach der Datensatz-ID in der URL fort. Dies auf false zu setzen scheint auf der Grundlage des Lesens der Funktion dieses Arguments nicht intuitiv zu sein, jedoch ergab dies die gewünschten Ergebnisse der Benennung der Datei nach dem tatsächlichen Dateinamen.

Ich habe auch das Mime-Type-Juwel verwendet und füge folgendes zu meiner video_uploader.rb-Datei hinzu:

%Vor%

Dieser Edelstein setzt anscheinend den mime-type erraten von der Dateierweiterung im Dateinamen. Dies machte es unnötig, dass ich Folgendes festlegen musste: Geben Sie explizit die send_file-Argumente in meiner download_file-Methode ein.

    
acoustic_north 10.03.2013 21:35
quelle