railsで画像投稿アプリのようなものを作成しています。
画像投稿する際はクライアントサイドからS3に直接投稿するようにしています。
しかし1枚投稿するとテーブルの画像カラムに保存される値がAWSのパスとActionDispatch::Http::UploadedFile:という値の2種類が保存されてしまいます。
(下記)
irb(main):001:0> Image.all Image Load (2.2ms) SELECT "images".* FROM "images" LIMIT $1 [["LIMIT", 11]] => #<ActiveRecord::Relation [#<Image id: 73, file: " <ActionDispatch::Http::UploadedFile:0x00007fde343...", post_id: 54, created_at: "2021-05-16 12:43:47", updated_at: "2021-05-16 12:43:47", place: "[\"konno\"]">, #<Image id: 74, file: "https://teratail.s3.ap- northeast-1.amazonaws.com/...", post_id: 54, created_at: "2021-05-16 12:43:47", updated_at: "2021-05-16 12:43:47", place: "[\"konno\"]">]>
これをAWSのパスのみ保存したいです。方法をご教授いただきたいです。
関連コード
post.rb
class Post < ApplicationRecord has_many :images, dependent: :destroy accepts_nested_attributes_for :images end
image.rb
class Image < ApplicationRecord belongs_to :post end
konno.html.erb
<% @image.each do |obj| %> <div style="display: inline-block;"> <%= image_tag obj.file %> <% if obj.post.nogimasa.username==current_nogimasa.username || current_nogimasa.admin? %> <div style="display: flex; justify-content: space-between;"> <div id="favos_buttons_<%= obj.id %>" > <%= render partial: "favos/favo", locals: { obj: obj} %> </div> <div> <p><a href="/nogizakas/<%=obj.post.nogimasa.nogizaka.id %>" style="color: purple;"><%= obj.post.nogimasa.username %></a></p> </div> <%= button_to "/posts/konno/#{obj.id}", method: :delete, data: {confirm: "この写真を本当に削除しますか?" } do %> <i class="fas fa-trash trash"></i> <% end %> </div> <% else %> <div style="display: flex; justify-content: center; position: relative;"> <div style="position: absolute; left: 0;" id="favos_buttons_<%= obj.id %>" > <%= render partial: "favos/favo", locals: { obj: obj} %> </div> <div> <p><a href="/nogizakas/<%=obj.post.nogimasa.nogizaka.id %>" style="color: purple;"><%= obj.post.nogimasa.username %></a></p> </div> </div> <% end %> </div> <% end %>
new_konno.html.erb
<h2 class="text-white" style="padding-top: 10px;">投稿</h2> <p class="post" style="text-align: right;"><a href="/posts/2012/konno">戻る>></a></p> <p style="text-align: right;"><a href="/nogitops">トップページへ>></a></p> <%= form_for(@post, url:{controller:"posts", action:"create_konno"}, html: { class: 'directUpload', data: { 'form-data' => (@s3_direct_post.fields), 'url' => @s3_direct_post.url, 'host' => URI.parse(@s3_direct_post.url).host } }) do |f| %> <div class="form-group"> <%= f.fields_for :images do |i|%> <%= i.file_field :file, multiple: true, name: "images[file][]", ref: "productImage" %> <%= i.hidden_field :place, :value=> "konno", multiple: true, name: "images[place][]" %> <% end %> </div> <%= f.submit "投稿", class: "btn btn-primary" %> <% end %> <%= @s3_direct_post.inspect %> <script> $(function() { $('.directUpload').find("input:file").each(function(i, elem) { var fileInput = $(elem); var form = $(fileInput.parents('form:first')); var submitButton = form.find('input[type="submit"]'); var progressBar = $("<div class='bar'></div>"); var barContainer = $("<div class='progress'></div>").append(progressBar); fileInput.after(barContainer); fileInput.fileupload({ fileInput: fileInput, url: form.data('url'), type: 'POST', autoUpload: true, formData: form.data('form-data'), paramName: 'file', dataType: 'XML', replaceFileInput: false, progressall: function (e, data) { console.log('progressall'); var progress = parseInt(data.loaded / data.total * 100, 10); progressBar.css('width', progress + '%') }, start: function (e) { console.log('start'); submitButton.prop('disabled', true); progressBar. css('background', 'green'). css('display', 'block'). css('width', '0%'). text("Loading..."); }, done: function(e, data) { console.log('done'); submitButton.prop('disabled', false); progressBar.text("Uploading done"); // extract key and generate URL from response var key = $(data.jqXHR.responseXML).find("Key").text(); var url = 'https://' + form.data('host') + '/' + key; var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url }) form.append(input); form.submit(); }, fail: function(e, data) { submitButton.prop('disabled', false); progressBar. css("background", "red"). text("Failed"); } }); }); }); </script>
posts_controller.rb
class PostsController < ApplicationController def konno @image=Image.where(place: "[\"konno\"]") end def new_konno @s3_direct_post = S3_BUCKET.presigned_post(key: "uploads/#{SecureRandom.uuid}/${filename}", success_action_status: "201", acl: 'public-read') @post=Post.new @post.images.new end def create_konno @post=Post.new(post_params) if @post.save! params[:images][:file].each do |a| @post.images.create!(file: a, post_id: @post.id, place: params[:images][:place]) end end redirect_to "/posts/2012/konno" end private def post_params params.permit(images_attributes: [:file, :place , :file_tmp, :_destroy, :id]).merge(nogimasa_id: current_nogimasa.id) end
あなたの回答
tips
プレビュー