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

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

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

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

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

SNS

SNS(ソーシャル・ネットワーキング・サービス)は、 人と人とのつながりを促進したり、サポートしたりすることが可能なコミュニティ型のWebサービスです。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

2回答

510閲覧

<Laravel> ミニマムなSNSサイトでコメント機能の実装

KIYZ

総合スコア17

MySQL

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

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

SNS

SNS(ソーシャル・ネットワーキング・サービス)は、 人と人とのつながりを促進したり、サポートしたりすることが可能なコミュニティ型のWebサービスです。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

4クリップ

投稿2018/05/03 11:30

前提

勉強のためにLaravel 5.1 LTSでシンプルなSNSサイトを開発しています。

実装した主な機能

  • ユーザー登録・ログイン認証
  • フォロー機能
  • 投稿機能
  • お気に入り機能
  • ユーザー一覧表示
  • フォロー・フォロワー一覧表示
  • 投稿一覧表示
  • お気に入り一覧表示

実現したいこと

現在、投稿に対してコメントする機能を実装しようとしています。
DBへの書き込みには $fillable を用いて実装したいと思っています。

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

一先ず、ページ上に設置したフォームからコメントを送信して、それをDBに書き込めるようにしようとしているところですが、これが実装できないため、コメントを表示するための view ファイルはまだ仮の状態です。

フォームからコメントを送信すると下記のエラーメッセージが出ます。

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`microposts`.`comments`, CONSTRAINT `comments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE) (SQL: insert into `comments` (`comment`, `updated_at`, `created_at`) values (コメントテスト, 2018-05-03 19:50:00, 2018-05-03 19:50:00))

試したこと

エラーはDBの外部キー制約関係の問題のようですので、試しに comments テーブル作成時に定義した全ての外部キー制約を dropForeign したところ、comment テーブルの comment, created_at, updated_at カラムには期待通りの値が書き込まれましたが、それ以外で必要な user_id と micropost_id カラムに値が書き込まれません。

自信がない部分等

リレーション関連と CommentsController@store での処理に自信がありませんが、具体的にどうすれば良いのかは分かりません。
ご教授よろしくお願い致します。

現状のコード

こちらからGitHub上で全てのファイルをご確認頂けます。

コメント用テーブル
2018_04_29_180548_create_comments_table.php

php

1<?php 2 3use Illuminate\Database\Schema\Blueprint; 4use Illuminate\Database\Migrations\Migration; 5 6class CreateCommentsTable extends Migration 7{ 8 9 public function up() 10 { 11 Schema::create('comments', function (Blueprint $table) { 12 $table->increments('id'); 13 $table->integer('user_id')->unsigned()->index(); 14 $table->integer('micropost_id')->unsigned()->index(); 15 $table->string('name'); // しばらくは使う予定無し 16 $table->string('email'); // しばらくは使う予定無し 17 $table->text('comment'); 18 $table->boolean('approved'); // しばらくは使う予定無し 19 $table->timestamps(); 20 21 $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); 22 $table->foreign('micropost_id')->references('id')->on('microposts')->onDelete('cascade'); 23 }); 24 } 25 26 public function down() 27 { 28 Schema::drop('comments'); 29 } 30} 31

コメント用のモデル
Comment.php

php

1<?php 2 3namespace App; 4 5use Illuminate\Database\Eloquent\Model; 6 7class Comment extends Model 8{ 9 public function micropost() 10 { 11 return $this->belongsTo(Micropost::class); 12 } 13} 14

投稿用のモデル
Micropost.php

php

1<?php 2 3namespace App; 4 5use Illuminate\Database\Eloquent\Model; 6 7class Micropost extends Model 8{ 9 protected $fillable = ['content', 'user_id']; 10 11 public function user() 12 { 13 return $this->belongsTo(User::class); 14 } 15 16 public function favorites() // リレーションの定義 17 { 18 return $this->belongsToMany(User::class, 'favorites', 'micropost_id', 'user_id')->withTimestamps(); 19 } 20 21 public function is_favorited_by($user_id) 22 { 23 return $this->favorites()->where('user_id', $user_id)->exists(); 24 } 25 26 public function comments() 27 { 28 return $this->hasMany(Comment::class); 29 } 30} 31

コメント用のコントローラー
CommentsController.php

php

1 2<?php 3 4namespace App\Http\Controllers; 5 6use Illuminate\Http\Request; 7 8use App\Http\Requests; 9use App\Http\Controllers\Controller; 10use App\User; 11use App\Micropost; 12use App\Comment; 13 14class CommentsController extends Controller 15{ 16// その他アクション省略 17 public function store(Request $request) 18 { 19 // $this->validate($request, [ 20 // 'content' => 'required|max:255', 21 // ]); 22 23 // 最終的には $fillable で実装 24 $comment = new Comment; 25 $comment->comment = $request->comment; 26 $comment->save(); 27 28 return redirect()->back(); 29 } 30 31 public function show($micropost_id) 32 { 33 $micropost = Micropost::find($micropost_id); 34 $user = User::where('id', $micropost->user_id)->first(); 35 36 return view('comments.comments', compact('micropost', 'user')); 37 } 38// その他アクション省略 39}

コメント 投稿フォーム・表示用の view
comments.blade.php

php

1@extends('layouts.app') 2 3@section('content') 4<div class="media-left"> 5 <img class="media-object img-rounded" src="{{ Gravatar::src($user->email, 50) }}" alt=""> 6</div> 7<div class="media-body"> 8 <div> 9 {!! link_to_route('users.show', $user->name, ['id' => $user->id]) !!} <span class="text-muted">posted at {{ $micropost->created_at }}</span> 10 </div> 11 <div> 12 <p>{!! nl2br(e($micropost->content)) !!}</p> 13 </div> 14 <div class="post-footer"> 15 <div class="btn-group"> 16 @include('favorites.favorite_button') 17 </div> 18 <div class="btn-group"> 19 @if (Auth::user()->id == $micropost->user_id) 20 {!! Form::open(['route' => ['microposts.destroy', $micropost->id], 'method' => 'delete']) !!} 21 {!! Form::submit('Delete', ['class' => 'btn btn-danger btn-xs']) !!} 22 {!! Form::close() !!} 23 @endif 24 </div> 25 <!--ここにマージンを挿入--> 26 <div class="row"> 27 <aside class="col-xs-3"> 28 {!! Form::open(['route' => 'comments.store']) !!} 29 <div class="form-group"> 30 {!! Form::textarea('comment', old('comment'), ['class' => 'form-control', 'rows' => '5']) !!} 31 </div> 32 {!! Form::submit('Post comment', ['class' => 'btn btn-primary btn-block']) !!} 33 {!! Form::close() !!} 34 </aside> 35 </div> 36 <!--ここに境界線を挿入--> 37 38 <!--ここにコメント一覧をループで挿入--> 39 40 </div> 41</div> 42@endsection

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

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

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

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

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

guest

回答2

0

CommentsController@storeでuser_idとmicropost_idを指定してないからでは。

$comment->user_id = $request->user()->id;

view側に$micropostのidも隠しフィールドで入れるかルーティングで$micropost_idを入れる。

もしくは関連したモデルの挿入
https://readouble.com/laravel/5.6/ja/eloquent-relationships.html#inserting-and-updating-related-models
この辺は若干ややこしいので試して覚えるしかない。

$micropost->comments()->create([ 'comment' => $request->comment, 'user_id' => $request->user()->id, 'micropost_id' => $micropost_id, ]);

投稿2018/05/03 11:52

kawax

総合スコア10377

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

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

KIYZ

2018/05/03 12:28 編集

ご回答誠にありがとうございます。 CommentsController@storeで、 下記のようにした場合は同ファイルで micropost が undefined になり、 ① $micropost->comments()->create([ 'comment' => $request->comment, 'user_id' => $request->user()->id, 'micropost_id' => $micropost_id, ]); ② $comment = $micropost->comments()->create([ 'comment' => $request->comment, 'user_id' => $request->user()->id, 'micropost_id' => $micropost_id, ]); 下記のようにした場合は質問時と同じエラーが出てしまいます。 ③ $comment = new Comment; $comment->comment = $request->comment; $comment->user_id = $request->user()->id; $comment->save();
Lulucom

2018/05/09 06:21

@KIYZ > 下記のようにした場合は同ファイルで micropost が undefined になり、 おそらく以下のようなコードが抜けているのではないでしょうか。 comments.blade.phpのform内で {{!! Form::hidden('micropost_id', $micropost->id) !!}} CommentsController@storeで $micropost_id = $request->micropost_id;
KIYZ

2018/05/10 10:55

ご指摘ありがとうございます。 comments.blade.php の フォームを生成する部分を {!! Form::open(['route' => ['comments.store', $micropost->id]]) !!} として、 CommentsController@storeで Comment::create([ 'user_id' => $request->user()->id, 'micropost_id' => $request->micropost_id, 'comment' => $request->comment, ]); とするとフォームから送信したデータを comments テーブルの各カラムに書き込むことができました。 CommentsController@store で問題だったのはDBに書き込みたい情報を明示していなかったことで、 comments.blade.php で問題だったのはフォームからコントローラーのアクションに対して "コメントされる micropost の id" を送信していなかったこと、という認識で正しいのでしょうか? よろしくお願いします。
Lulucom

2018/05/10 12:45

> という認識で正しいのでしょうか? はい。
KIYZ

2018/05/10 12:47

大変勉強になりました。 ありがとうございます。
guest

0

自己解決

kawaxさんと Lulucom さんにご教授頂いたことを組み合わせて実装することができたのでここにまとめさせて頂きます。

以下、コメント送信フォームから送信したデータを comments テーブルに書き込む方法です。
(DBに保存したコメントデータを取得し、ページに表示させることはまだ行っていません。)

comments.blade.php

php

1{!! Form::open(['route' => ['comments.store', $micropost->id]]) !!}

CommentsController@store

php

1 public function store(Request $request) 2 { 3 // バリデーション 4 5 Comment::create([ 6 'user_id' => $request->user()->id, 7 'micropost_id' => $request->micropost_id, 8 'comment' => $request->comment, 9 ]); 10 11 return redirect()->back(); 12 }

参考にしたドキュメント

CommentsController@store は、上記ドキュメントのようにして実装することも可能でした。

php

1 public function store(Request $request, $id) 2 { 3 // バリデーション 4 5 $micropost = Micropost::find($id); 6 7 $micropost->comments()->create([ 8 'user_id' => $request->user()->id, 9 'micropost_id' => $request->micropost_id, 10 'comment' => $request->comment, 11 ]); 12 13 return redirect()->back(); 14 }

投稿2018/05/10 13:05

KIYZ

総合スコア17

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問