I've got a system in which there are users
who create posts and they can comment on posts
as well.
Here are migrations:
users
table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('gender')->default('Male');
$table->string('email')->unique();
$table->string('city')->default('Peshawar');
$table->string('avatar')->default('user.png');
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
posts
table
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('p_id');
$table->text('description');
$table->integer('user_id'); // this should be user id nothing else
$table->timestamps();
});
}
comments
table
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id'); // who has done comment
$table->integer('post_id'); // on which post comment has been done
$table->text('body');
$table->timestamps();
});
}
Models
User
Model
class User extends Authenticatable{
use Notifiable;
// custom function used for relationshisp
// user can have many posts
public function posts(){
return $this->hasMany('App\Post');
}
// user can have many comments as well
public function comments(){
return $this->hasMany('App\Comment');
}
}
Post
Model
class Post extends Model{
// posts belongs to one user
public function user(){
return $this->belongsTo('App\User');
}
public function comments(){
return $this->hasMany('App\Comment');
}
}
Comment
Model
class Comment extends Model
{
// doing this we could insert data into comment table
protected $fillable =['user_id','post_id','body'];
// we need two(2) relations here
// relation of comment with post
// relation of comment with user
// 1. comment belongs to one post
public function post(){
return $this->belongsTo('App\Post');
}
// 2. comment belongs to a user as well
public function user(){
return $this->belongsTo('App\User');
}
}
route
Route::get('/home', 'HomeController@index')->name('home');
Here is the index
method in HomeController
public function index(){
$posts = Post::with('comments')->get();
// $comments = Comment::all();
return view('home')->with( array('posts'=>$posts ) );
}
Problem
So when I visit /home
I want to get all posts with their comments .
As you can see I've retrieved posts
with their comment
like this:
$posts = Post::with('comments')->get();
And then I'm passing it to home.blade.php
. Here is what I'm doing at home.blade.php
to achieve this task.
View /home.blade.php
@foreach($posts as $post)
<h4 class="media-heading">{{$post->user->name}}</h4>
<small>{{$post->created_at}}</small>
<p>{{$post->description}}</p>
<!-- trying to retrieve comments with each post -->
@if (count($post->comments))
@foreach($post->commnents as $comment)
<small>$comment->body</small>
@endforeach
@else
No comments Found
@endif
@endforeach
It gives me this error
Undefined variable: post (View: F:\\application\\resources\\views\\home.blade.php)
Keeping in mind those models
and their relationships
with each other, am I doing it in the wrong way to retrieve comments for each post? If so, how can I get all the posts
with their comments
and when there are no comments
it should say no comments found
.
Here is what the result return by dd($posts)
dd($posts) returning this , have a look at the comments field, that is empty.
The network
tab is showing the following Please help, Thanks to everyone.
its probably because of this..
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('p_id'); <---
$table->text('description');
$table->integer('user_id'); // this should be user id nothing else
$table->timestamps();
});
}
any reason why you are using p_id instead of id? relations work so that id of post is matched to the post_id in the comments table.. if you using this u have to specify this custom key when you are creating the relationship..
check out https://laravel.com/docs/5.8/eloquent-relationships#defining-relationships
Try passing your post custom key as third argument to the relation:
Comment Model
public function post(){
return $this->belongsTo('App\Post', 'post_id', 'p_id');
}
Maybe a better option will be, change the key of the table posts to 'id' to agree with the conventions of Laravel. Create a new migration and run it.
Schema::table('posts', function (Blueprint $table) {
$table->renameColumn('p_id', 'id');
});
Another option would be, creating the foreign key constraints, to force referential integrity at the database level:
posts table
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('p_id');
$table->text('description');
$table->integer('user_id')->unsigned();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
});
}
comments table
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id')->unsigned();
$table->integer('post_id')->unsigned();
$table->text('body');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('post_id')->references('p_id')->on('posts');
});
}
You will have to rollback and re-run the migrations (you will lose the data saved in DB).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.