解決したいこと
ユーザーが写真付きの記事を投稿した際にターミナルでrollback transactionのエラーが表示され、DBに保存ができない状態を解決したいです。
解決するために試したこと
1、 rollback transactionのエラーについて気になったので調べました。
簡単にいうと保存するためのカラムの培養が不足しておりsaveができない状態とのこと。
2、 コントローラのcreateアクションにある@dish.saveの記述を@dish.save!にすることでエラーの内容が表示されるとのことでそちらも試して見たところ「Validation failed: User must exist」エラーが出ました。直訳すると「バリデーションに失敗しました。ユーザーは存在しなければなりません」となりました。Userモデルに値が入っていないためバリデーションで弾かれていた様子。
3、 2で出てきたエラー「Validation failed: User must exist」を調べると解決の鍵となる内容の記事に出会いました。
解決方法
optional: trueをDishモデルに記述
*/app/models/dish.rb
class Dish < ApplicationRecord
has_one_attached :dish_image
belongs_to :user#, optional: true
has_many :comments, dependent: :destroy
has_many :favorits, dependent: :destroy
end
これは外部キーがnilでもDBに保存できるとのことでした。
でもよくよく考えるとnilではいけないのでコメントアウトしました。
さらに見ていくとコントローラのストロングパラメータに以下のような記述が、、
merge(user_id: current_user.id)
すぐに調べたところmergeメソッドとあり、実際の記述がなくてもidなどを運べるという内容の記述でした!
この記述でuser_idカラムを運ぶことができエラーが解消されました。
以前学習してうっすら覚えていたform_withで使用したhidden_fieldに似ているような感じがしました。idなどを運べるようにするのはこれからも必要になると思うのでhidden_fieldも復習します。
1日かかってようやく解決できた、、
時間はかかったけど嬉しい、、
関連コード
*/controllers/dishes_controller.rb
class DishesController < ApplicationController
def new
@dish = Dish.new
end
def create
@dish = Dish.new(dish_params)
@dish.save!
#binding.pry
redirect_to user_path(current_user.id)
end
private
def dish_params
params.require(:dish).permit(:dish_name, :introduction, :user_id).merge(user_id: current_user.id)
end
end
*/models/dish.rb
class Dish < ApplicationRecord
has_one_attached :dish_image
belongs_to :user#, optional: true
has_many :comments, dependent: :destroy
has_many :favorits, dependent: :destroy
end
*/dishes/new.html.erb
<h1>Dishes#new</h1>
<p>Find me in app/views/dishes/new.html.erb</p>
<h2></h2>
<%= form_with model: @dish, url: dishes_path(current_user.id), method: :post do |f| %>
<%= f.label "料理名" %>
<%= f.text_field :dish_name %>
<%= f.label "料理画像" %>
<%= f.file_field :dish_image, accept: "image/*" %>
<%= f.label "紹介文" %>
<%= f.text_area :introduction %>
<%= f.submit "CookOPする" %>
<% end %>