2017-01-24 4 views
1

Ich habe seit etwa 5 Stunden kämpfen versucht zu verstehen, warum Shrine meine Uploads blockiert. Ich bekomme entweder Fehler wie "Schrein: Ungültige Datei" oder "Erwartetes Array, aber habe String" in starken params. Wenn keine Fehler vorliegen, werden die Bilder nicht gespeichert.Schrein mit Rails mehrere polymorphe Bild-Uploads

require "image_processing/mini_magick" 

class ImageUploader < Shrine 
    include ImageProcessing::MiniMagick 

    plugin :activerecord 
    plugin :backgrounding 
    plugin :cached_attachment_data 
    plugin :determine_mime_type 
    plugin :delete_raw 
    plugin :direct_upload 
    plugin :logging, logger: Rails.logger 
    plugin :processing 
    plugin :remove_attachment 
    plugin :store_dimensions 
    plugin :validation_helpers 
    plugin :versions 

    Attacher.validate do 
    validate_max_size 2.megabytes, message: 'is too large (max is 2 MB)' 
    validate_mime_type_inclusion ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'] 
    end 

    def process(io, context) 
    case context[:phase] 
    when :store 
     thumb = resize_to_limit!(io.download, 200, 200) 
     { original: io, thumb: thumb } 
    end 
    end 
end 

class Image < ActiveRecord::Base 
    include ImageUploader[:image] 
    belongs_to :imageable, polymorphic: true 
end 

class Product < ApplicationRecord 

    has_many :images, as: :imageable, dependent: :destroy  
    accepts_nested_attributes_for :images, allow_destroy: true 
... 

# Strong Params: 

def product_params 
    params.require(:product).permit(
    :name, :brand_id, :category_id, :price, :compare_price, :description, 
    images_attributes: { image: [] }, 
    product_properties_attributes: [:id, :property_id, :value] 
) 
... 

Und meine Ansicht:

<%= f.fields_for :images do |image_form| %> 
    <%= image_form.file_field :image, multiple: true %> 
    <% end %> 

Accor Alles, was ich in den Dokumenten oder aus den Gorails gelesen habe, sollte funktionieren. Muss ich den images_attributes Hash umstrukturieren? Ich versuchte auch, direct_uploads zu verwenden, aber kämpfte, um die presigned_url zu erhalten, um mit S3 zu arbeiten.

Refile macht das wirklich einfach, also werde ich wahrscheinlich weinen zurück zu dem laufen.

Gibt es etwas, was ich offensichtlich falsch mache?

Antwort

3

Entsprechend der fields_for documentation wird der bereitgestellte Block für jedes Bild in der project.images Sammlung aufgerufen. Wenn Ihr Produkt derzeit keine Bilder enthält, wird der Block nicht aufgerufen (gemäß den Dokumenten).

Für verschachtelte Attribute, arbeiten Sie die folgenden Parameter zu übermitteln müssen, wenn das Produkt zu schaffen:

product[images_attributes][0][image] = <file object or data hash> 
product[images_attributes][1][image] = <file object or data hash> 
product[images_attributes][2][image] = <file object or data hash> 
... 

Wenn man sich die „Multiple Files“ Shrine Führung aussehen, ist es empfehlenswert, dass Sie nur eine einzelne Datei Feld haben die akzeptieren mehrere Dateien:

<input type="file" name="file" multiple> 

Und dann direkte Setup-Uploads für dieses Feld (eine JavaScript-Datei-Upload-Bibliothek wie jQuery-Datei-hochladen verwenden), dynamisch für jeden hochgeladen das image Feld erzeugt Datei mit dem Dateidaten Hash hochgeladen bevölkert:

<input type="hidden" name="product[images_attributes][0][image]" value='{"id":"...","storage":"cache","metadata":{...}}'> 
<input type="hidden" name="product[images_attributes][1][image]" value='{"id":"...","storage":"cache","metadata":{...}}'> 
.... 

Alternativ können Sie nur können Benutzer mehrere Dateien anhängen, die alle an die App übermittelt, und denaturiert, sie dann in der Steuerung:

class ProductsController < ApplicationController 
    def create 
    images_attributes = params["files"].map { |file| {image: file} } 
    Product.create(product_params.merge(images_attributes: images_attributes)) 
    end 
end 
+0

Danke sehr viel! Ich habe diesen Prozess frustrierend genug gefunden, um einfach auf Büroklammer zu wechseln. Ich stimme stark mit Ihrem Blogpost überein und die Dokumentation ist gut, aber wenn ich nur will, dass die Dinge funktionieren, ist mein Fallback Büroklammer. Außerdem scheint das Go-Rails-Video für den Jquery-Datei-Upload anstößig lang zu sein, wenn andere (ältere) Lösungen gut funktionieren und weniger Konfiguration benötigen. Ich würde liebend gerne eine Schrein-Schiene-Edelstein-Lösung sehen (ich werde vielleicht selbst daran arbeiten). –

+0

Es tut mir leid, das zu hören. Wie auch immer, danke für das Feedback, ich werde daran arbeiten, die Shrine-Dokumentation über mehrere Datei-Uploads zu verbessern. –

+0

Ich wollte dich nur updaten. Ich habe deine Methode versucht und hatte einfach keinen Erfolg (ich benutze auch S3). Refile war sehr einfach in meiner Rails-App zu implementieren, also bleibe ich dabei, bis ich später umschalten kann. Ich bin mir auch bewusst, dass du kein riesiger Rails-Fan bist ... aber ich glaube an deinen Blogbeitrag über Schrein und würde gerne ein Fürsprecher sein. –

Verwandte Themen