Rails activestorageを使用して複数のファイルをアップロードする適切な方法は何ですか
概要
複数の「サポート写真」ファイルをアイテムモデルにアップロードしようとしています。
複数のファイルをアップロードする必要があるため、サポートする写真ファイルには has_many_attached の関連付けがあります。
item.rb
class Item < ApplicationRecord
belongs_to :user
has_one_attached :cover_photo do |attachable|
attachable.variant :medium, resize_to_limit:[300,300]
attachable.variant :large, resize_to_limit:[1200,1000]
end
has_many_attached :supporting_photos do |attachable|
attachable.variant :medium, resize_to_limit:[300,300]
attachable.variant :large, resize_to_limit:[1200,1000]
end
ユーザーが記入するフォームには、file_field タグを持つ複数の div があり、ユーザーが複数の「サポート写真」を添付できるようにします。
items/new.html.erb
<div class="mt-2 flex justify-center rounded-lg border border-dashed border-gray-900/25 px-6 py-10">
<div class="text-center">
<div class="mt-4 flex text-sm leading-6 text-gray-600">
<%= form.file_field :supporting_photos, direct_upload:true %>
</div>
<p class="text-xs leading-5 text-gray-600">or drag and drop</p>
<p class="text-xs leading-5 text-gray-600">PNG, JPG, GIF up to 10MB</p>
</div>
</div>
</div>
<div class="sm:col-span-2">
<div class="mt-2 flex justify-center rounded-lg border border-dashed border-gray-900/25 px-6 py-10">
<div class="text-center">
<div class="mt-4 flex text-sm leading-6 text-gray-600">
<%= form.file_field :supporting_photos, direct_upload:true %>
</div>
<p class="text-xs leading-5 text-gray-600">or drag and drop</p>
<p class="text-xs leading-5 text-gray-600">PNG, JPG, GIF up to 10MB</p>
</div>
</div>
</div>
<div class="sm:col-span-2">
<div class="mt-2 flex justify-center rounded-lg border border-dashed border-gray-900/25 px-6 py-10">
<div class="text-center">
<div class="mt-4 flex text-sm leading-6 text-gray-600">
<%= form.file_field :supporting_photos, direct_upload:true %>
</div>
<p class="text-xs leading-5 text-gray-600">or drag and drop</p>
<p class="text-xs leading-5 text-gray-600">PNG, JPG, GIF up to 10MB</p>
</div>
</div>
</div>
最後に、これが私のアイテムコントローラーです。これを行う方法を調べたとき、これが私が見つけた解決策でしたが、「許可されていないパラメーター: :supporting_photos」というエラーが発生しました。コンテキスト: { コントローラー: ItemsController、アクション: create、リクエスト: #<ActionDispatch…’ ターミナル コンソールで、フォームを読み込むときにブラウザーで #<actiondispatch の未定義メソッドもそれぞれ’
誰かこれを行う適切な方法を知っていますか?お願いします、そしてありがとう
def new
# @item = item.new
@item = current_user.items.build
end
def create
# @item = item.new(item_params)
@item = current_user.items.build(item_params.except(:supporting_photos))
supporting_photos = params[:item][:supporting_photos]
if supporting_photos
supporting_photos.each do |supporting_photo|
@item.supporting_photos.attach(supporting_photo)
end
end
if @item.save
redirect_to sell_sale_path
else
render :new, status: :unprocessable_entity
end
end
private
def item_params
params.require(:item).permit(:name, :brand, :colour, :condition, :department, :category, :price, :is_sold, :cover_photo, :description, supporting_photos: [])
end
ユーザーにとってより直感的なものにしたいので、複数のファイルフィールドも必要です これが私が目指していることです
これとは対照的に
解決策
複数のファイルフィールドは必要ありません。複数の true 属性を持つ 1 つだけ
また、許可するには、このパラメータを :item キーでラップする必要があることにも注意してください。基本的に、この目的のために :model キーとともに form_with を使用することが可能です。
<%#= app/views/items/new.html.erb %>
<%= render "form", item: @item %>
<%#= app/views/items/_form.html.erb %>
<%= form_with(model: item) do |form| %>
<%= form.file_field :supporting_photos, direct_upload: true, multiple: true %>
<%= form.submit %>
<% end %>
ただし、アイテムを更新するときに既存の写真を保持し、このフォームを部分的に再利用する必要がある場合は、複数の非表示フィールドを追加する必要がある場合があります。
<% item.supporting_photos.each do |sp| %>
<%= form.hidden_field :supporting_photos, multiple: true, value: sp.signed_id %>
<% end %>
バックエンド側では、明示的に写真を添付したり (特に保存前に) パラメータを反復したりする必要はなく、十分です。
# app/controllers/items_controller.rb
def create
@item = Item.new(item_params)
if @item.save
redirect_to item_url(@item)
else
render :new, status: :unprocessable_entity
end
end
private
def item_params
params.require(:item).permit(supporting_photos: [])
end