Simple comments model and migration

Submitted by Riari - 7 years ago

This employs Eloquent's polymorphic relationships (https://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations) to provide a simple flat comment thread system.

// Migration class

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCommentsTable extends Migration
{
    /**
    * Run the migrations.
    *
    * @return void
    */
    public function up()
    {
        Schema::create('comments', function ($table) {
            $table->increments('id')->unsigned();
            $table->integer('user_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users');
            $table->string('commentable_type');
            $table->integer('commentable_id')->unsigned();
            $table->text('body');
            $table->timestamps();
        });
    }
    
    /**
    * Reverse the migrations.
    *
    * @return void
    */
    public function down()
    {
        Schema::drop('comments');
    }
}

// Comment model

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['user_id', 'body'];

    /**
     * Relationship: author
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function author()
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    /**
     * Relationship: commentable models
     *
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
     */
    public function commentable()
    {
        return $this->morphTo();
    }
}

// 'Commentable' model
// (You could also write a CommentableTrait to use in as many
// models as you like)

namespace App;

use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    /**
     * Relationship: comments
     *
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
     */
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

// User model

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    /**
     * Relationship: comments
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

// Usage examples

// Fetch the comments written by a user
User::find(1)->comments;

// Fetch a model's comment paginator
Article::find(1)->comments()->orderBy('created_at', 'desc')->paginate(); 

// Fetch the author of a comment
Comment::find(1)->author; 

// Add a new comment
$article->comments()->create([
    'user_id' => Auth::id(),
    'body' => $request->input('body')
]);