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

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

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

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

2808閲覧

掲示板の投稿に対してコメント機能を実装したいです。モデルのリレーションが上手くいかず困っています。

yyuukkii

総合スコア7

Laravel

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/04/11 08:36

編集2020/04/11 13:26

前提・実現したいこと

PHP laravelのフレームワークでシンプルな掲示板を作成しています。

一つの投稿に対して複数コメントを出来るように実装したいと考えています。

参考はこちらの記事の方の方法を参考にしました。
https://blog.hiroyuki90.com/articles/laravel-bbs/

ただもともと投稿を出来る画面をはじめに作っていたのでそこに追加する形で実装しようとしています。
Seederなどは使わず進めています。

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

投稿された内容とコメントのデータを取得しviewに表示させる段階を作っています。

hasMany()とbelongsTo()を使用しモデル、migrationファイルの連携をし、
投稿された内容を写すことは出来たのですが、投稿に対してのコメントを表示させようとviewファイルに変数を書き込むと下記のようなエラーが出てしまいます。

ErrorException (E_ERROR)
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'comments.talk_id' in 'where clause' (SQL: select * from comments where comments.talk_id = 2 and comments.talk_id is not null) (View: /home/ec2-user/environment/talkroom/resources/views/talkroom/index.blade.php)

上記のエラーを見ると恐らくtalk_idというカラムが存在していないと認識したのですが、talk_idというカラムは定義しておらずmysqlで確認してもありませんでした.

投稿のデータを保存するTalk modelのidとコメントのデータを保存するComment modelのpost_idを上手く繋げたいのですが、どのあたりに間違いがあるのか調べてもなかなか解決しなかったのでこちらで質問させていただきます。

お手数ですが宜しくお願い致します。

足りない情報があれば追記していきますので併せて宜しくお願い致します。

該当のソースコード

##migration file

<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; use App\Talk; class CreateCommentsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('comments', function (Blueprint $table) { $table->increments('id'); $table->integer('post_id')->unsigned(); $table->string('name')->nullable(); $table->text('body'); $table->timestamps(); $table->foreign('post_id')->references('id')->on('talks'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('comments'); } }
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; use App\Comment; class CreateTalksTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('talks', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->string('name')->nullable(); $table->string('body'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('talks'); } }

##Model

namespace App; use Illuminate\Database\Eloquent\Model; use App\Talk; class Comment extends Model { protected $fillable = [ 'name', 'body', ]; public static $rules = array( 'name' => 'required', 'body' => 'required', ); public function talks() { return $this->belongsTo('App\Talk'); } }
namespace App; use Illuminate\Database\Eloquent\Model; use App\Comment; class Talk extends Model { protected $fillable = [ 'title', 'name', 'body', ]; public static $rules = array( 'title' => 'required', 'body' => 'required', ); public function comments() { return $this->hasMany('App\Comment'); } }

##Controller

<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Talk; use App\Comment; class TalkroomController extends Controller { public function index(Request $request) { $cond_title = $request->cond_title; if ($cond_title != '') { $posts = Talk::where('title', 'like', '%'.$cond_title.'%')->get(); } else { $posts = Talk::orderBy('created_at', 'desc')->get(); } return view('talkroom.index', ['posts' => $posts, 'cond_title' => $cond_title]); }

##index view file // $post->commentsを書き加えるとエラーが起きてしまい消すと投稿画面のみちゃんと表示されます。

@extends('layouts.front') @section('content') <div class="container mt-4"> <div class="border p-4"> <h1 class="h5 mb-4"> <div class="form-group row"> <label class="col-md-2" for="title">タイトル</label> <div class="col-md-10"> <div class="title"> {{ str_limit($talk_form->title, 50) }} </div> </div> </div> <div class="form-group row"> <label class="col-md-2" for="name">名前</label> <div class="col-md-10"> <div class="name"> {{ str_limit($talk_form->name, 20) }} </div> </div> </div> <div class="form-group row"> <label class="col-md-2">本文</label> <div class="col-md-10"> <div class="body"> {{ str_limit($talk_form->body, 100) }} </div> </div> </div> <div class="form-group row"> <div class="col-md-10"> <input type="hidden" name="id" value="{{ $talk_form->id }}"> {{ csrf_field() }} </div> </div> <form class="mb-4" method="post" action="{{ action('CommentsController@post') }}" enctype="multipart/form-data"> {{ csrf_field() }} @if (count($errors) > 0) <ul> @foreach ($errors->all() as $e) <li>{{ $e }}</li> @endforeach </ul> @endif <div class="form-group col-md-6 mx-auto"> <label for="name">名前</label> <div class="col-md-6 mx-auto"> <input type="text" class="form-control" name="name" value="{{ old('name') }}"> </div> </div> <div class="form-group col-md-6 mx-auto"> <label class="col-md-2">本文</label> <div class="col-md-6 mx-auto"> <textarea id="body" class="form-control" name="body" rows="10">{{ old('body') }}</textarea> </div> </div> <div class="col-md-6 mx-auto"> <button type="submit" class="btn btn-primary"> コメントする </button> </div> </form> <section> <h2 class="h5 mb-4"> コメント </h2> @foreach($post->comments as $comment) <div class="border-top p-4"> <time class="text-secondary"> {{ $comment->created_at->format('Y.m.d H:i') }} </time> <p class="mt-2"> {{ $comment->body }} </p> </div> @endforeach </section> </div> </div> @endsection

試したこと

migration fileのメソッドや型を変えてみたり
コメント機能に関する記事やリレーションに関しての記事を調べたのですがわかりませんでした。

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

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

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

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

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

m.ts10806

2020/04/11 13:03 編集

質問タグに「Laravel」はつけられたほうが良いかと。
yyuukkii

2020/04/11 13:24

わかりました!
guest

回答1

0

ベストアンサー

Talkというモデル名に基づいてtalk_idという名前のカラムにアクセスされています。

以下のどちらかに変更する必要がありそうです。

  • commentsテーブルのカラムpost_idtalk_idに改名
  • モデルTalkPostに改名

(追記)
それが大変そうならhasManyに引数を追加してpost_idを指定する方法でも良いかもしれません。分かりづらくなる気はしますが...

php

1 public function comments() 2 { 3 return $this->hasMany('App\Comment', 'post_id'); 4 }

投稿2020/04/11 14:14

編集2020/04/11 14:35
Lulucom

総合スコア1899

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

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

yyuukkii

2020/04/12 05:33

Lulucomさんありがとうございます! 解決いたしました。 migration fileをtalk_idに変更しリレーションは出来ました! リレーションを行うと自動的にmigration fileに定義した名前に変更されてしまうという認識でよろしいでしょうか? そのあたり詳しい解説が見当たりませんでした。 (この場合commentsとtalksというmigrationがありcommentsにはpost_idを書きtalksのidとつなげようとしました。しかし実際にテーブル上に作成されたのはtalk_idでリレーション出来ませんでした。) もし宜しければご教授お願いいたします!
Lulucom

2020/04/12 05:47 編集

> リレーションを行うと自動的にmigration fileに定義した名前に変更されてしまうという認識でよろしいでしょうか? > そのあたり詳しい解説が見当たりませんでした。 いえ、Talkというモデル名をもとに外部キー名はtalk_idだとLaravelが推測します。以下のページで解説されています。 https://readouble.com/laravel/7.x/ja/eloquent-relationships.html (あと、ご質問にはLaravelのバージョンも記載された方が良いです) > commentsにはpost_idを書き...しかし実際にテーブル上に作成されたのはtalk_id いえ、そのようなことにはならないはずですが... 開発中に、実行済のマイグレーションを修正される場合は、まずロールバック、マイグレーションの修正、マイグレートという手順を踏む必要があります。その点は大丈夫でしょうか。(ロールバックすると当然テーブルやカラムのデータは削除されますのでご注意ください)
yyuukkii

2020/04/12 13:07

ありがとうございます。 マイグレーションはロールバックを行い再度作り直しましたが、それでもtalk_idが反映されてしまい混乱していました。 laravelの推測のあたりは全然わからないので頂いたURLから確認してみます。 バージョンの件かしこまりました! 色々ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問