#投稿文に対してコメントをつける機能を実装する
エラー文
SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert into comments
(body
, updated_at
, created_at
) values (あああああああああ, 2019-06-17 20:28:43, 2019-06-17 20:28:43))
検証①
user_idに値が設定されていないという文面。たぶんuser_idがうまくpostされてないのかな?と思った。
user_idとpost_idはcommentsテーブルの必須項目のカラム。
しかし、ブラウザでHTMLソースを見ても<input type="hidden" name="user_id" value="{{ $user->id }}">
で値が入っている。
@extends('layouts.app')
@section('title', 'レビューページ')
@section('content')
<div class="container mt-4">
<div class="border p-4">
<h1 class="h5 mb-4">
{{ $post->title }}
</h1>
<div class="user-name text-right">{{ $post->user->name }}さん</div>
<p class="mb-5">
{!! nl2br(e($post->body)) !!}
</p>
@if (Auth::check())
<form class="mb-4" method="POST" action="/post/{{ $post->id }}">
@csrf
<input type="hidden" name="post_id" value="{{ $post->id }}">
<input type="hidden" name="user_id" value="{{ $user->id }}">
<div class="form-group">
<label for="body">
本文
</label>
<textarea
id="body"
name="body"
class="form-control {{ $errors->has('body') ? 'is-invalid' : '' }}"
rows="4"
>{{ old('body') }}</textarea>
@if ($errors->has('body'))
<div class="invalid-feedback">
{{ $errors->first('body') }}
</div>
@endif
</div>
<div class="mt-4">
<button type="submit" class="btn btn-primary">
コメントする
</button>
</div>
</form>
@endif
<section>
検証②
(SQL: insert into comments
(body
, updated_at
, created_at
)...
SQL文にuser_idとpost_idのカラム指定がないぞ。なんで?コントローラ内の記述にミスがないか確認。
$params = $request->all();
の中身にuser_idとpost_idが入ってないのかな?
エラーを吐き出している処理のComment::create($params);
をコメントアウトして$params
の中身を確認。
$params
にはuser_idとpost_idを含めた正常な値が配列で表示された。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
use App\Comment;
class CommentController extends Controller
{
public function store(Request $request)
{
$validate_rule = [
'post_id' => 'required|exists:posts,id',
'body' => 'required|max:2000',
];
$this->validate($request, $validate_rule);
$params = $request->all();
return $params;
//Comment::create($params);
return redirect()->route('posts_show', ['id' => $request->post_id]);
}
}
検証③
値もしっかり入っててpostされているのになんでDBに保存できないんだろうか?
Comment::create($params);
の処理を作っているモデルの方を確認する。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Post;
use App\User;
class Comment extends Model
{
protected $fillable =['body'];
public function post()
{
return $this->belongsTo('App\Post');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
あれ??protected $fillable =['body'];
がbodyフィールドだけになっている...違和感を感じ
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Post;
use App\User;
class Comment extends Model
{
protected $fillable =['body', 'post_id', 'user_id];
public function post()
{
return $this->belongsTo('App\Post');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
protected $fillable =['body', 'post_id', 'user_id];
に修正。
無事、コメント投稿された。とても時間がかかってしまった。。。
#なぜこのエラーの解決にハマったのか(時間がかかったか)
- 実行されたSQL文を勘違いしていた。値が取得できていないからuser_idとpost_idのカラム指定がないと思っていた。
-
$params
の中身を確認する方法が最初わからなかった。 - 勘や予測を頼りにデバッグしていた。
デバッグは勘や読みに頼りすぎず、観察することを優先する。原因を切り分け順序を追って一つ一つ潰していくこと。効率のよいデバッグ方法は順を追って観察すること。
#今後の対策として実行
- ログにSQLクエリを出力させて、普段から見るようにした。