Dieses Mal scheint sich das Timing für das Speichern von Bildern von Rails 6 geändert zu haben, also habe ich es überprüft.
$ rails -v
Rails 6.0.2.1
$ rails active_storage:install
$ rails db:migrate
Ich werde das Endprodukt veröffentlichen.
Vorschau zur Route hinzufügen.
route.rb
Rails.application.routes.draw do
resources :users do
collection do
post :preview
patch :preview
end
end
end
Ermöglicht dem Modell, Bilder mit has_one_attached zu verarbeiten.
user.rb
class User < ApplicationRecord
has_one_attached :image
end
Als nächstes kommt der Controller. Dieses Mal möchte ich eine Vorschau-Funktion hinzufügen, also habe ich eine Vorschau-Aktion hinzugefügt.
user_controller.rb
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
@users = User.all
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
@user = User.new
end
# GET /users/1/edit
def edit
end
.
.
.
.
def preview
@user = User.new(user_params)
image_binary = ''
if @user.image.attached?
image_binary = @user.attachment_changes['image'].attachable.read
else
saved_user = User.find_by(id: params[:id])
if saved_user.present? && saved_user.image.attached?
image_binary = saved_user.image.blob.download
end
end
@image_enconded_by_base64 = Base64.strict_encode64(image_binary)
render template: 'users/_preview', layout: 'application'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
@user = User.find(params[:id])
end
# Only allow a list of trusted parameters through.
def user_params
params.require(:user).permit(:name, :image)
end
end
Schließlich HTML.
ruby:new.html.erb
<h1>New User</h1>
<%= render 'form', user: @user %>
<%= link_to 'Back', users_path %>
ruby:_form.html.erb
<%= form_with(model: user, local: true) do |form| %>
<% if user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
<%= form.label :image %>
<%= form.file_field :image %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
ruby:show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @user.name %>
<% if @user.image.attached? %>
<%= image_tag @user.image %>
<% end %>
</p>
<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>
ruby:_preview.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @user.name %>
<% if action_name == 'preview' %>
<img src="data:image/png;base64,<%= @image_enconded_by_base64 %>" />
<% else %>
<%= image_tag @member.image %>
<% end %>
</p>
Sie sind jetzt bereit.
Ich werde das Bild sofort hochladen.
Wenn Sie die Test-JPEG-Datei hochladen und auf die Schaltfläche "Benutzer erstellen" klicken
erstellen ist erfolgreich. Wenn Sie das hier hochgeladene Bild sehen möchten
irb(main):005:0> @user.image.attachment
ActiveStorage::Attachment Load (1.5ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = ? AND "active_storage_attachments"."record_type" = ? AND "active_storage_attachments"."name" = ? LIMIT ? [["record_id", 1], ["record_type", "User"], ["name", "image"], ["LIMIT", 1]]
=> #<ActiveStorage::Attachment id: 1, name: "image", record_type: "User", record_id: 1, blob_id: 1, created_at: "2020-05-21 09:04:12">
Ich habe festgestellt, dass das Bild existiert.
Versuchen Sie dann eine neue Vorschau.
Laden Sie auf die gleiche Weise die Datei template.jpg hoch und klicken Sie auf die Schaltfläche "Vorschau", um das Bild zu überprüfen.
Dann
> @user.image.attachment
NameError: uninitialized constant #<Class:0x00007fd450065780>::Analyzable
from /usr/local/bundle/gems/activestorage-6.0.3.1/app/models/active_storage/blob.rb:26:in `<class:Blob>'
Abwesend! !!
> params[:user][:image]
=> #<ActionDispatch::Http::UploadedFile:0x000055892ec2b598
@content_type="image/jpeg",
@headers=
"Content-Disposition: form-data; name=\"user[image]\"; filename=\"\xE3\x83\x95\xE3\x82\x9A\xE3\x83\xAC\xE3\x83\x92\xE3\x82\x99\xE3\x83\xA5\xE3\x83\xBC.jpg\"\r\nContent-Type: image/jpeg\r\n",
@original_filename="Vorschau.jpg ",
@tempfile=#<File:/tmp/RackMultipart20200522-1-ha9tz1.jpg>>
Überprüfen Sie die Parameter. Wird es nicht einfach durch Hochladen eines Bildes gespeichert?
Wenn Sie sich auf Folgendes beziehen https://github.com/rails/rails/pull/33303
auf Schienen5
@user.image = params[:image]
Es ist das Timing, wenn Sie es in das Attribut setzen!
Auf keinen Fall gibt es eine solche Änderung der Schienen 6! !! Wenn dies unverändert bleibt, kann das Bild zum Zeitpunkt der Vorschau nicht an View übergeben werden (ohne das Bild in der Instanz zu speichern).
Als ich nach einem guten Weg suchte
・ Https://github.com/rails/rails/pull/33303
・ Https://stackoverflow.com/questions/57564796/reading-from-active-storage-attachment-before-save
dort gab es!!
record.attachment_changes['<attributename>'].attachable
Versuchen!
> @user.attachment_changes['image'].attachable
=> #<ActionDispatch::Http::UploadedFile:0x000055892ec2b598
@content_type="image/jpeg",
@headers=
"Content-Disposition: form-data; name=\"user[image]\"; filename=\"\xE3\x83\x95\xE3\x82\x9A\xE3\x83\xAC\xE3\x83\x92\xE3\x82\x99\xE3\x83\xA5\xE3\x83\xBC.jpg\"\r\nContent-Type: image/jpeg\r\n",
@original_filename="Vorschau.jpg ",
@tempfile=#<File:/tmp/RackMultipart20200522-1-ha9tz1.jpg>>
des Weiteren
@user.attachment_changes['image'].attachable.read
Ich konnte die Binärdaten mit ↑ abrufen, wenn ich sie also mit Base64 codiere und übergebe
@image_enconded_by_base64 = Base64.strict_encode64(@user.attachment_changes['image'].attachable.read)
Es ist fertig! !!
Ich wusste nicht, dass sich der Zeitpunkt für das Speichern von Active Strage geändert hat. Wenn Sie das Bild berühren möchten, ohne es zu speichern
record.attachment_changes['<attributename>'].attachable.read
Lesen Sie die Binärdatei mit Base64! !! (Es muss nicht Base64 sein)
Bitte lassen Sie mich wissen, ob es einen anderen guten Weg gibt.
Recommended Posts