1

So, I checked a tutorial for a simple blog that had function to post comments on a post. I had my post migration already and I wanted to add comments to post. The posts have a picture of an item and a description. So my migration is:

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts' ,function(Blueprint $table){

            $table->increments('id')->unsigned()->unique();
            $table->unsignedInteger('user_id')->unsigned();
            $table->unsignedInteger('item_id')->unsigned();
            $table->string('picture', 255)->nullable();
            $table->text('description')->nullable();

            $table->foreign('user_id')
                ->references('id')
                ->on('users')
                ->onDelete('cascade');


            $table->foreign('item_id')
                ->references('id')
                ->on('items')
                ->onDelete('cascade');


            $table->timestamps();
        });

    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('posts');
    }
}

so I have a table with the post id, the user_id of the poster, the item_id of the item whose picture is being posted, the picture and a description.

Now I thought, ok I have to add comments to these posts so I need a comments table and I made one like this:

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()->default(0);
            $table->foreign('post_id')
                ->references('id')->on('posts')
                ->onDelete('cascade');
            $table -> integer('user_id')->unsigned()->default(0);
            $table->foreign('user_id')
                ->references('id')->on('users')
                ->onDelete('cascade');
            $table->text('body');
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        // drop comment
        Schema::drop('comments');
    }
}

where I have the id of the comments, the post_id of the post the comment refers to and, the user_id of the commenter and the comment body.

This should be a one to many relationship problem right? A post can have many comments.

So the models are:

class Comment extends Model
{

    /**
     *
     * The comment belongs to one author
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function author()
    {
        return $this->belongsTo('App\User');
    }

    /**
     *
     * The comment belongs to one post
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function post()
    {
        return $this->belongsTo('App\Post');
    }

}

...

class Post extends Model
{

    /**
     *
     * a post has many comments
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function comments()
    {
        return $this->hasMany('App\Comments');
    }

    /**
     *
     * a post belongs to one author
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function author()
    {
        return $this->belongsTo('App\User');
    }

}

...

class User extends Model
{

  //..... (some more stuff here not related to comments.

    public function comments()
    {
        return $this->hasMany('App\Comment');
    }
}

Now the point is, if I want to return all users posts WITH comments and comments author, how should I modify the models?

Chriz74
  • 1,410
  • 3
  • 23
  • 47
  • something like this should work Post::with('comments.author')->get() (this will give u all posts with comments and the comments author. – Achraf Khouadja May 17 '16 at 17:27
  • it returns an empty array: `$user = Auth::user(); $posts = Post::with('comments', 'author')->where('user_id', '=', $user )->get();` under the hood it performs this: `string(52) "select * from `users` where `users`.`id` = ? limit 1" string(41) "select * from `posts` where `user_id` = ?"` – Chriz74 May 17 '16 at 17:35
  • no not like this with('comments', 'author'), its a nested relation , with('comments.author') (if you want to get the comment author ofc, if u want with post author add this with('comments.author', 'author') – Achraf Khouadja May 17 '16 at 17:44
  • $user = Auth::user()->id this is the issue change it to add the id not the whole user – Achraf Khouadja May 17 '16 at 17:50
  • Yes I figured that out. And yes it works. But I have another question, how do you eager load the posts with comments and author from the model directly? – Chriz74 May 17 '16 at 17:53
  • post another question then and make this as answered. pls, to keep things clear – Achraf Khouadja May 17 '16 at 17:55

2 Answers2

1

you could do something like

$posts_with_comments = Post::with('author', 'comments')->get();

you can add as many relations as you want to load with it, check out the eager docs

https://laravel.com/docs/4.2/eloquent#eager-loading

William R.
  • 33
  • 5
  • hmm it works but author returns Null, so it must be wrong in the model. – Chriz74 May 17 '16 at 17:50
  • try this page http://stackoverflow.com/questions/24469122/laravel-belongsto-not-working and change the belongs to reflect your user id in your user model, `return $this->belongsTo('App\User', 'user_id');` – William R. May 17 '16 at 18:33
  • The problem now is a post has many comments, the comments are a nested collection with a nested collection (the author). So How in even do you prepare the final array to pass to the view with all this nested stuff?? – Chriz74 May 18 '16 at 15:52
  • that seems to be another question about how to pass information to views in nested collections, but how does the 'posts_with_comments' array look? can you var_dump it for me? – William R. May 19 '16 at 01:22
0

try this

$user = Auth::user(); $posts = Post::with('comments', 'author')->where('user_id', $user->id )->get();

you are using the user object not the user id in the 'where'

Achraf Khouadja
  • 6,119
  • 4
  • 27
  • 39