質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

1回答

1973閲覧

編集画面でupdateするとnullのファイル名がDBに保存されてしまう。

pontarou3

総合スコア18

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2020/03/27 08:31

編集2022/01/12 10:55

#前提・実現したいこと

■前提
・editアクションからupdateアクション間にて発生したエラーです
・テキストのみの投稿を編集時にエラー、または予期しないnullが発生

■実現したいこと
・編集画面で画像を添付し、updateまで機能させたい

#発生している問題・エラーメッセージ

テキストのみの、postを編集し、updateしようとすると、nullの画像ファイルが生成されてしまいます。
ArgumentError in Posts#indexと表示されています。
(これはnullの画像が発生しているためだと思います)
イメージ説明

nullの画像が生成されているデータベースです。
イメージ説明

#追加情報
paramsの記述とupdateメソッドあたり
でコードがおかしくなっているのではっというところまでわかりました。

#該当のソースコード

posts.controller.rb

ruby

1class PostsController < ApplicationController 2 3 before_action :set_post, except: [:index, :new, :create] 4 5 def index 6 @posts = Post.includes(:user, :images).all.order('created_at DESC') 7 end 8 def show 9 @post = Post.find(params[:id]) 10 end 11 def new 12 @post = Post.new 13 @post.images.new 14 end 15 def create 16 @post = Post.new(post_params) 17 if @post.save 18 redirect_to root_path, notice: "投稿しました" 19 else 20 flash[:alert] = "入力してください" 21 render partial:"form",locals: {post: new} 22 end 23 end 24 def edit 25 @post = Post.find(params[:id]) 26 end 27 28#ここから----------------- 29 def update 30 if @post.update(post_params) 31 redirect_to root_path, notice: "success" 32 else 33 flash[:alert] = "save error" 34 render :edit 35 end 36 end 37#ここまでの記述が怪しい----------------- 38 def destroy 39 @post.destroy 40 redirect_to root_path 41 end 42 43 private 44 45#ここから----------------- 46 def post_params 47 params.require(:post).permit(:title, :content, images_attributes: [:src, :_destroy, :id]).merge(user_id: current_user.id) 48 end 49#ここまでの記述が怪しい----------------- 50 51 def set_post 52 @post = Post.find(params[:id]) 53 end 54end

form.html.erb

ruby

1<%= form_for @post do |f| %> 2 <label>title</label> 3 <%= f.text_field :title, class: "form-control" %> 4 <div class = "form-group"> 5 <label>content</label> 6 <%= f.text_area :content, class: "form-control" %> 7 </div> 8 <div id="image-box"> 9 <div id="previews"> 10 <% if @post.persisted? %> 11 <% @post.images.each_with_index do |image, i| %> 12 <%= image_tag image.src.url, data: { index: i }, width: "100", height: '100' %> 13 <% end %> 14 <% end %> 15 </div> 16 <%= f.fields_for :images do |image| %> 17 <div data-index="<%= image.index %>" class="js-file_group"> 18 <%= image.file_field :src, class: 'js-file' %><br> 19 <span class="js-remove">削除</span> 20 </div> 21 <% if @post.persisted? %> 22 <%= image.check_box :_destroy, data:{ index: image.index }, class: 'hidden-destroy' %> 23 <% end %> 24 <% end %> 25 <% if @post.persisted? %> 26 <div data-index="<%= @post.images.count %>" class="js-file_group"> 27 <%= file_field_tag :src, name: "post[images_attributes][#{@post.images.count}][src]", class: 'js-file' %> 28 <div class="js-remove">削除</div> 29 </div> 30 <% end %> 31 </div> 32 <%= f.submit %> 33<% end %> 34

form.js

js

1$(document).on('turbolinks:load', ()=> { 2 const buildFileField = (num)=> { 3 const html = `<div data-index="${num}" class="js-file_group"> 4 <input class="js-file" type="file" 5 name="post[images_attributes][${num}][src]" 6 id="post_images_attributes_${num}_src"><br> 7 <div class="js-remove">削除</div> 8 </div>`; 9 return html; 10 } 11 const buildImg = (index, url)=> { 12 const html = `<img data-index="${index}" src="${url}" width="100px" height="100px">`; 13 return html; 14 } 15 16 let fileIndex = [1,2,3,4,5,6,7,8,9,10]; 17 lastIndex = $('.js-file_group:last').data('index'); 18 fileIndex.splice(0, lastIndex); 19 20 $('.hidden-destroy').hide(); 21 22 $('#image-box').on('change', '.js-file', function(e) { 23 const targetIndex = $(this).parent().data('index'); 24 const file = e.target.files[0]; 25 const blobUrl = window.URL.createObjectURL(file); 26 27 if (img = $(`img[data-index="${targetIndex}"]`)[0]) { 28 img.setAttribute('src', blobUrl); 29 } else { 30 $('#previews').append(buildImg(targetIndex, blobUrl)); 31 $('#image-box').append(buildFileField(fileIndex[0])); 32 fileIndex.shift(); 33 fileIndex.push(fileIndex[fileIndex.length - 1] + 1); 34 } 35 }); 36 37 $('#image-box').on('click', '.js-remove', function() { 38 const targetIndex = $(this).parent().data('index'); 39 const hiddenCheck = $(`input[data-index="${targetIndex}"].hidden-destroy`); 40 if (hiddenCheck) hiddenCheck.prop('checked', true); 41 42 $(this).parent().remove(); 43 $(`img[data-index="${targetIndex}"]`).remove(); 44 45 if ($('.js-file').length == 0) $('#image-box').append(buildFileField(fileIndex[0])); 46 }); 47});

#自分で調べたことや試したこと

①paramsの設定とparamsの呼び出し方が怪しい
②updateメソッドの書き方が怪しい

①に関して
・paramsの値にparams.require(:post).permit(:title, :content, images_attributes: [:src, :_destroy, :id])
と記述しており、まず、ここが怪しいと思ってます。ここの値を軸にしてupdateメソッドが動いていると思っいると思っているのですが

②paramsとupdateメソッドの書き方を工夫する必要がありそう???

現在paramsに記述しているものを下記のように条件分岐させることで解決できないかな?と考えました。

ruby

1def post_params 2 if @post.images.blank? 3 params.require(:post).permit(:title, :content).merge(user_id: current_user.id) 4 else 5 params.require(:post).permit(:title, :content, images_attributes: [:src, :_destroy, :id]).merge(user_id: current_user.id) 6 end 7 end

しかしこのような分岐の記述だと、

◯テキストは更新できても、
×画像の添付が更新がされなくなってしまいます。

その他調べて試行錯誤したのですが、うまくいっていません。

解決の仕方として・・・・

ruby

1 2def update 3 if #ここにsrcの情報が空だったら.update(non_images_post_params) 4 redirect_to root_path, notice: "success" 5 elsif #画像が添付されていたら 6 @post.update(post_params) 7 redirect_to root_path, notice: "success" 8 else 9 flash[:alert] = "save error" 10 render :edit 11 end 12 end

このような記述ができれば問題解決するのではないか?と考えています。

paramsかupdateメソッドあたりをいじれば解決しそうなのですが、どなたかお気づきになられた点がございましたらご指摘いただけますと幸いです。

#補足情報
念の為モデル情報を記載いたします。

ruby

1class Image < ApplicationRecord 2 mount_uploader :src, ImageUploader 3 belongs_to :post 4end

ruby

1class Post < ApplicationRecord 2 belongs_to :user 3 has_many :images, dependent: :destroy 4 5 accepts_nested_attributes_for :images, allow_destroy: true 6end

#追記情報

エラー発生時のパラメーターについて

Processing by PostsController#update as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"QfkhkxqxTiQP+6ju2R8D7+u9vrh7MFA7LG8B0koHc0Yq5bI7YOUcEUSfs6E5vZNXkkrhNaF3VU+m79H5jgYRCw==", "post"=>{"title"=>"タイトル", "content"=>"コンテント", "images_attributes"=>{"0"=>{"src"=>""}}}, "commit"=>"Update Post", "id"=>"78"} Post Load (0.4ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 78 LIMIT 1 CACHE Post Load (0.0ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 78 LIMIT 1 [["id", 78], ["LIMIT", 1]] User Load (0.6ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1 (0.2ms) BEGIN (0.3ms) ROLLBACK

以上となります。
ここまで見ていただきありがとうございます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s.k

2020/03/29 09:27 編集

updateした時のパラメータのログを質問に追記できますか?
pontarou3

2020/03/29 10:21

@s.k さん ご確認いただきありがとうございます。 一番下にparameterのログを追記いたしました。
guest

回答1

0

ログをみるとsrcの値が空なのでエラーが発生してしまっているのではないのでしょうか。

ruby

1"images_attributes"=>{"0"=>{"src"=>""}}}

なぜ、srcに値がないのかまではわからないのですが。
もし、以前保存した画像データを送るのならsrcに値をセットしてコントローラに渡しましょう。
{"0"=>{"src"=>""}}} のままだと空文字で更新されてしまいます。

そもそも、空でsrcを更新できてしまうのは問題ですのでバリデーションをかけた方がいいと思います。

ruby

1validates :src, presence: true

参考
【個人メモ】carrierwaveでcacheを取り回す

投稿2020/03/29 10:51

編集2020/03/29 10:52
s.k

総合スコア423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問