Dies ist eine Lösung, um mehrere Bilder mit Carrierwave in Rails 4 von Grund auf hochzuladen
Oder Sie finden eine funktionierende Demo:
Multiple Attachment Rails 4
Befolgen Sie dazu einfach diese Schritte.
rails new multiple_image_upload_carrierwave
In Edelsteindatei
gem 'carrierwave'
bundle install
rails generate uploader Avatar
Postgerüst erstellen
rails generate scaffold post title:string
Erstellen Sie ein post_attachment-Gerüst
rails generate scaffold post_attachment post_id:integer avatar:string
rake db:migrate
In post.rb.
class Post < ActiveRecord::Base
has_many :post_attachments
accepts_nested_attributes_for :post_attachments
end
In post_attachment.rb
class PostAttachment < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
belongs_to :post
end
In post_controller.rb
def show
@post_attachments = @post.post_attachments.all
end
def new
@post = Post.new
@post_attachment = @post.post_attachments.build
end
def create
@post = Post.new(post_params)
respond_to do |format|
if @post.save
params[:post_attachments]['avatar'].each do |a|
@post_attachment = @post.post_attachments.create!(:avatar => a)
end
format.html { redirect_to @post, notice: 'Post was successfully created.' }
else
format.html { render action: 'new' }
end
end
end
private
def post_params
params.require(:post).permit(:title, post_attachments_attributes: [:id, :post_id, :avatar])
end
In Ansichten / Beiträge / _form.html.erb
<%= form_for(@post, :html => { :multipart => true }) do |f| %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<%= f.fields_for :post_attachments do |p| %>
<div class="field">
<%= p.label :avatar %><br>
<%= p.file_field :avatar, :multiple => true, name: "post_attachments[avatar][]" %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
So bearbeiten Sie einen Anhang und eine Liste der Anhänge für einen Beitrag.
In Ansichten / Beiträge / show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Title:</strong>
<%= @post.title %>
</p>
<% @post_attachments.each do |p| %>
<%= image_tag p.avatar_url %>
<%= link_to "Edit Attachment", edit_post_attachment_path(p) %>
<% end %>
<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>
Aktualisieren Sie das Formular, um die Ansichten eines Anhangs / post_attachments / _form.html.erb zu bearbeiten
<%= image_tag @post_attachment.avatar %>
<%= form_for(@post_attachment) do |f| %>
<div class="field">
<%= f.label :avatar %><br>
<%= f.file_field :avatar %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Ändern Sie die Aktualisierungsmethode in post_attachment_controller.rb
def update
respond_to do |format|
if @post_attachment.update(post_attachment_params)
format.html { redirect_to @post_attachment.post, notice: 'Post attachment was successfully updated.' }
end
end
end
In Rails 3 müssen keine starken Parameter definiert werden, und da Sie attribute_accessible sowohl im Modell als auch accept_nested_attribute für das Post-Modell definieren können, ist das Attribut access in Rails 4 veraltet.
Zum Bearbeiten eines Anhangs können nicht alle Anhänge gleichzeitig geändert werden. Daher ersetzen wir den Anhang nacheinander, oder Sie können ihn gemäß Ihrer Regel ändern. Hier zeige ich Ihnen nur, wie Sie einen Anhang aktualisieren.
create
Aktion? Schienen und Trägerwellen sind intelligent genug, um Sammlungen automatisch zu speichern.:_destroy
Teil)Wenn wir uns die Dokumentation von CarrierWave ansehen, ist dies jetzt tatsächlich sehr einfach.
https://github.com/carrierwaveuploader/carrierwave/blob/master/README.md#multiple-file-uploads
Ich werde Product als Modell verwenden, um die Bilder als Beispiel hinzuzufügen.
Holen Sie sich die Hauptniederlassung Carrierwave und fügen Sie sie Ihrer Gemfile hinzu:
Erstellen Sie eine Spalte im beabsichtigten Modell, um ein Array von Bildern zu hosten:
Führen Sie die Migration aus
Fügen Sie Bilder zum Modellprodukt hinzu
Fügen Sie Bilder zu starken Parametern in ProductsController hinzu
Lassen Sie Ihr Formular mehrere Bilder akzeptieren
In Ihren Ansichten können Sie auf die Bilder verweisen, die das Bildarray analysieren:
Wenn Sie mehrere Bilder aus einem Ordner auswählen, entspricht die Reihenfolge genau der Reihenfolge, in der Sie sie von oben nach unten aufnehmen.
quelle
UndefinedConversionError ("\x89" from ASCII-8BIT to UTF-8)
Bei SSR-Lösungen funktioniert sie einwandfrei Rails 4.xx, aber ich stehe vor Herausforderungen (mit Rails 5.xx), dh das SpeichernActionDispatch::Http::UploadedFile
in der Datenbank anstelle des Dateinamens. Es werden auch keine Dateien in öffentlichen Ordnern für einen bestimmten Pfad im Uploader gespeichert.Einige kleinere Ergänzungen zur SSR- Antwort:
accepts_nested_attributes_for erfordert nicht, dass Sie den Controller des übergeordneten Objekts ändern. Also wenn zu korrigieren
zu
dann werden alle diese Controller-Änderungen wie diese überflüssig:
Außerdem sollten Sie
PostAttachment.new
dem übergeordneten Objektformular Folgendes hinzufügen :In Ansichten / Beiträge / _form.html.erb
Dies würde diese Änderung im Controller des übergeordneten Controllers überflüssig machen:
Weitere Informationen finden Sie unter Rails fields_for-Formular nicht angezeigt, verschachteltes Formular
Wenn Sie Rails 5 verwenden, ändern Sie den
Rails.application.config.active_record.belongs_to_required_by_default
Wert vontrue
infalse
(in config / initializers / new_framework_defaults.rb) aufgrund eines Fehlers in accepts_nested_attributes_for (andernfalls funktioniert accept_nested_attributes_for unter Rails 5 im Allgemeinen nicht).EDIT 1:
Um über zerstören hinzuzufügen :
In models / post.rb.
In Ansichten / Beiträge / _form.html.erb
Auf diese Weise benötigen Sie einfach überhaupt keinen Controller für ein untergeordnetes Objekt! Ich meine, es wird nichts mehr
PostAttachmentsController
benötigt. Der Controller (PostController
) des übergeordneten Objekts wird ebenfalls fast nicht geändert. Das einzige, was Sie dort ändern, ist die Liste der Parameter auf der Whitelist (einschließlich der untergeordneten objektbezogenen Parameter) wie folgt:Deshalb
accepts_nested_attributes_for
ist das so erstaunlich.quelle
<%= d.text_field :copyright, name: "album[diapos_attributes][][copyright]", class: 'form-field' %>
schreibt das Copyright nur auf den letzten Datensatz und nicht auf alle.Außerdem habe ich herausgefunden, wie der Upload mehrerer Dateien aktualisiert werden kann, und ich habe ihn auch ein wenig überarbeitet. Dieser Code gehört mir, aber Sie bekommen die Drift.
quelle
Hier ist mein zweiter Refaktor im Modell:
Regler:
Im Motherboard-Modell:
quelle
Wenn Sie die Zuordnung verwenden, müssen
@post.post_attachments
Sie die nicht festlegenpost_id
.quelle