Schrein mit Schienen mehrere polymorphe Bild hochlädt

Ich habe gekämpft, für über 5 Stunden versucht zu verstehen, warum Schrein blockiert meine uploads. Entweder ich bekomme Fehler wie „Schrein: Ungültige Datei“ oder „Array Erwartet, aber bekam string“ starke params. Wenn es keine Fehler, die Bilder sind nicht wirklich gespeichert.

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 %>

Nach allem, was ich gelesen habe, die docs oder aus gorails, dies sollte funktionieren. Muss ich die Umstrukturierung der images_attributes hash? Ich habe auch versucht, mit direct_uploads, aber gekämpft, um die presigned_url arbeiten mit S3.

Refile macht das wirklich einfach, so dass ich wahrscheinlich schreiend zurück.

Gibt es etwas, was ich offensichtlich falsch mache?

InformationsquelleAutor Kevin Brown | 2017-01-24



One Reply
  1. 5

    Entsprechend der fields_for – Dokumentation, wird die angegebene block aufgerufen wird, werden für jedes Bild in der project.images Sammlung. Also, wenn Ihr Produkt bisher noch keine Bilder, die blockieren, können nicht aufgerufen werden (entsprechend der Dokumentation).

    Für verschachtelte Attribute zu arbeiten, benötigen Sie für die Weiterleitung der folgenden Parameter bei der Erstellung des Produktes:

    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 „Mehrere Dateien“ Schrein guide, es wird empfohlen, dass Sie nur eine einzige Datei Feld, die akzeptiert mehrere Dateien:

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

    Und dann setup direkten uploads für dieses Feld mit Uppy, dynamisch die Generierung der image Feld für jede hochgeladene Datei aufgefüllt mit der hochgeladenen Datei Daten-hash:

    <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 einfach lassen Sie die Benutzer mehrere Dateien anzuhängen, die sind alle eingereicht, um die app, und dann destructure Sie 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
    

    In diesem Fall müssen Sie sicherstellen, dass das HTML-Formular hat die enctype="multipart/form-data" – Attribut gesetzt ist (ansonsten nur die Dateien Dateinamen vorgelegt bekommen, nicht die Dateien selbst).

    • Ich danke Ihnen sehr! Ich habe festgestellt, diesen Prozess frustrierend genug, um wechseln Sie einfach auf die Büroklammer. Ich Stimme stark mit Ihrem blog-post & die Dokumentation ist gut, aber wenn ich einfach nur will, dass die Dinge zu arbeiten, meine fallback ist die Büroklammer. Zusätzlich ist der go-Schienen-video für jquery-file-upload scheint widerlich lang, wenn andere (ältere) Lösungen funktionieren gut und nehmen weniger Konfiguration. Ich würde gerne sehen, ein shrine-rails gem Lösung (ich kann schauen in die Herstellung selbst).
    • Tut mir Leid, das zu hören. Wie auch immer, danke für das feedback, ich werde daran arbeiten, auf die Verbesserung der Schrein Dokumentation um mehrere Datei-uploads.
    • Wollte nur aktualisieren Sie. Ich habe versucht, Ihre Methode und wusste nicht nur, Erfolg haben (ich bin auch mit S3). Refile war sehr einfach zu implementieren in meiner rails-app, also werde ich mit dem stick, bis ich Zeit habe um zu wechseln später. Ich bin auch bewusst nicht du bist ein riesiges Schienen-fan…aber ich glaube in Ihrem blog-post über Schrein und würde gerne zu einem Anwalt.
    • Vielen Dank für das lassen mich wissen. Hehe, ja, ich bin nicht eine riesige Rails-fan, aber ich bin ein fan von Dingen, die sehr leicht zu set-up, also das ist definitiv etwas, was ich brauche, um herauszufinden, hier. Sobald die Dokumentation auf mehrere Datei-uploads verbessert, wird es einfacher für jemanden zu erstellen shrine-rails gem.
    • FWIW, Rails 5 hat die Dinge ein wenig anders (ich würde sagen leichter, aber vielleicht …). Sie können Ihre polymorph-Tabelle und erstellen Sie die druckbaren Beziehung, sondern nutzen Sie die :optional => true-Schalter auf der polymorphe Klasse zu vermeiden, die „Eltern müssen zuerst erstellt werden“
    • Ich weiß, dies ist ein Alter thread aber ich ‚ ve wurde kämpfen mit diesem für fast eine Woche! Diese Lösung funktioniert leider nicht. param[„Dateien“] nicht alle Dateien in der box und auch der {image: Datei} funktioniert ebenfalls nicht (auch wenn Sie zu beheben, die param). Ich weiß nicht, die Antwort noch… immer noch kämpfen, um herauszufinden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.