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

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

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

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

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

アップロード

アップロードは特定のファイルをウェブサーバに送るプロセスのことを指します。

Ruby on Rails

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

Q&A

1回答

995閲覧

images_attributesを使って画像を保存できない

naota7118

総合スコア7

Ruby

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

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

アップロード

アップロードは特定のファイルをウェブサーバに送るプロセスのことを指します。

Ruby on Rails

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

0グッド

0クリップ

投稿2020/08/16 11:01

編集2020/08/16 11:15

転職活動用の個人アプリを作成しています。
食べたものやカロリー値などを投稿してカロリーコントロールしやすくするためのダイエットアプリを作成しています。

カロリー値やPFC値をpostモデルに保存するのと同時に、画像はimageモデルに保存したいのですが、それができずに困っています。

ビューの書き方も間違っていて、表示ができないのはあとで自分で考えて修正しますが、それ以前にMySQLに保存する段階でつまずいているので、まずそこの解決するためのヒントを頂ければ幸いです。

よろしくお願いします。

前提・実現したいこと

画像を保存できるようにしたい。
images_attributesを使って、カロリー値やPFC値を投稿するときに、画像データはpostモデルに紐づく形でimageモデルに保存できるようにしたい。

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

投稿データがpostモデルに保存されるのと同時に、画像データはimageモデルに保存されるようにしたいのにできない。
imagesテーブルのimageカラムがnilになってしまう。

ターミナル

pry(#<PostsController>)> @post.images Image Load (0.4ms) SELECT `images`.* FROM `images` WHERE `images`.`post_id` = 167 ↳ app/controllers/posts_controller.rb:33 => [#<Image:0x00007fdeaf3c5650 id: 23, image: nil, post_id: 167, created_at: Sun, 16 Aug 2020 09:33:38 UTC +00:00, updated_at: Sun, 16 Aug 2020 09:33:38 UTC +00:00>]

イメージ説明
id=21~23の部分だけ見てください。

該当のソースコード

コントローラー(posts_controller.rb)

def index @posts = Post.all.includes(:user).order("created_at DESC").page(params[:page]).per(5) @post = Post.new @post.images.build end def create @post = Post.new(post_params) if @post.save redirect_back(fallback_location: root_path) else @posts = Post.includes(:user) flash.now[:alert] = '必須項目をしてください。' redirect_back(fallback_location: root_path) end end private def post_params params.require(:post).permit(:food, :calorie, :protein, :fat, :carbo, :text, images_attributes: [:image]).merge(user_id: current_user.id) end

indexアクションでは、@post.images.buildで@postに紐づく形でimageを保存するための空き箱を作ります。

createアクションでは、form_withで入力された情報をプライベートメソッドのpost_paramsで受け取って、@postに代入しています。

この時、post_paramsのimages_attributes: [:image]で画像データも一緒に保存されるはずなのですが、実際は保存されてくれません。

postモデル(post.rb)
class Post < ApplicationRecord has_many :images, dependent: :destroy accepts_nested_attributes_for :images, allow_destroy: true end
ビュー(_main.html.haml)
.main .section .new-post = form_with model: @post, id: 'new_post' do |f| .input-box (省略) .icon .image-upload = f.fields_for :images do |image| %i.fa.fa-camera.fa-2x = image.file_field :image, multiple: true, class: 'image_upload' .btn-square = f.submit '投稿する', class: 'post-btn'

親モデルにaccepts_nested_attributes_for: 〇〇(子モデルのテーブル名)と書くと、親モデルの情報と一緒にその子モデルの情報も保存されます。

今回で言うと親モデル(postモデル)の情報(投稿データ。食べたもの、カロリー値など)と同時に画像データは子モデル(imageモデル)に別で保存されます。

参考にしたページhttps://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

imageモデル(image.rb)

class Image < ApplicationRecord belongs_to :post mount_uploader :image, ImageUploader end

CarrierWaveを使って画像をアップロードしたい場合、画像を保存するテーブル(今回はimagesテーブル)に追加したカラムの名前をmount_uploaderに指定する。

試したこと

paramsの中身とpost_paramsの中身を確認した。
その結果、paramsでは画像データ(image5.png)が入っていたが、post_paramsには画像データが入ってなかった。

ターミナル
pry(#<PostsController>)> params => <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"h63zuMZOESYUInxzZD8jFqMbInn7kkMcWj1auQF2Irl1agWdILfmE8SEX9gYsvobDQbcAe336Nsu4SRCHezT7w==", "post"=><ActionController::Parameters {"food"=>"うどん", "calorie"=>"10", "protein"=>"10", "fat"=>"10", "carbo"=>"10", "text"=>"うどんを食べました。", "images_attributes"=>{"0"=>{"image"=>[#<ActionDispatch::Http::UploadedFile:0x00007fdea83150b8 @tempfile=#<Tempfile:/var/folders/sy/26p55v5j47s2zjd8h7vr8f6h0000gn/T/RackMultipart20200816-2275-g3cxd2.png>, @original_filename="image5.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"post[images_attributes][0][image][]\"; filename=\"image5.png\"\r\nContent-Type: image/png\r\n">]}}} permitted: false>, "commit"=>"投稿する", "controller"=>"posts", "action"=>"create"} permitted: false> [2] pry(#<PostsController>)> post_params Unpermitted parameter: :image => <ActionController::Parameters {"food"=>"うどん", "calorie"=>"10", "protein"=>"10", "fat"=>"10", "carbo"=>"10", "text"=>"うどんを食べました。", "images_attributes"=><ActionController::Parameters {"0"=><ActionController::Parameters {} permitted: true>} permitted: true>, "user_id"=>17} permitted: true>

わからないこと・疑問点

なぜparamsには画像データが入っているのに、post_paramsでは画像データが入っていないのか?

→paramsには問題なく入るのは、form_withのフォームで投稿してるから。paramsには入ってるのにpost_paramsには入っていないということは、posts_controllerのプライベートメソッドpost_paramsのimages_attributes: [:image]この部分の書き方が間違っているのか?

posts_controller.rb
private def post_params params.require(:post).permit(:food, :calorie, :protein, :fat, :carbo, :text, images_attributes: [:image]).merge(user_id: current_user.id) end

補足情報(FW/ツールのバージョンなど)

Ruby 2.5.1
Rails 5.2.4.3

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

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

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

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

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

guest

回答1

0

https://teratail.com/questions/88224
ここにありましたが:idが必要みたいです

images_attributes: [:id, :image]

投稿2020/08/16 12:36

nasuk47

総合スコア311

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

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

naota7118

2020/08/16 12:47

nasuk47さん ご回答いただきありがとうございます!教えていただいた通り`:id`を加えてみましたが、やはりpost_paramsに画像データが入ってくれず、画像は保存されませんでした。post_paramsただおかげさまで重要な見落としに気づくことができました。 Unpermitted parameter: :image このエラー文を見落としておりました。 紹介いただいた参考記事も同じエラー文となっていますが、これをヒントに探したいと思います。 [1] pry(#<PostsController>)> post_params Unpermitted parameter: :image => <ActionController::Parameters {"food"=>"うどん", "calorie"=>"100", "protein"=>"100", "fat"=>"100", "carbo"=>"100", "text"=>"うどん", "images_attributes"=><ActionController::Parameters {"0"=><ActionController::Parameters {} permitted: true>} permitted: true>, "user_id"=>17} permitted: true>
nasuk47

2020/08/16 12:58

解決できず申し訳ないです。 僕もよくわかっていませんがモデル名とカラム名が同じだダメみたいなこともあるんですかね?
naota7118

2020/08/16 13:09

nasuk47さん とんでもないです!回答いただけるだけでもありがたいですし、見落としに気づくことができたのでよかったです。 >僕もよくわかっていませんがモデル名とカラム名が同じだダメみたいなこともあるんですかね? スクールのチーム開発の時は、imagesテーブルのimageカラムでも問題なくいったので、モデル名とカラム名が同じだとダメというのはちょっと疑問です。 ぼくも全然わかってないので、自信はないのですが。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問