Laravel 모델관계

런던행·2021년 12월 24일
0

Laravel

목록 보기
2/3

Post <-> Comment (일대다 관계)
Post <-> PostDescription (일대일 관계)
Post <-> Label (다대다 관계)

마이그레이션

    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title', 100);
            $table->text('content');
            $table->timestamps();
        });
    }
    
    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('post_id');
            $table->string('content', 100);
            $table->timestamps();

            $table->foreign('post_id')
                ->references('id')
                ->on('posts');

        });
    }

    public function up()
    {
        Schema::create('post_descriptions', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('post_id');
            $table->string('content', 100);
            $table->timestamps();

            $table->foreign('post_id')
                ->references('id')
                ->on('posts');

        });
    }
    
    public function up()
    {
        Schema::create('labels', function (Blueprint $table) {
            $table->id();
            $table->string('name', 50);
            $table->timestamps();
        });
    }
    
    public function up()
    {
        Schema::create('label_post', function (Blueprint $table) {
            $table->unsignedBigInteger('post_id');
            $table->unsignedBigInteger('label_id');

            $table->foreign('post_id')
                ->references('id')
                ->on('posts');

            $table->foreign('label_id')
                ->references('id')
                ->on('labels');
                
            $table->unique(['post_id', 'label_id']);
            
        });
    }

모델 클래스

class Post extends Model
{
    use HasFactory;

    public function description()
    {
        return $this->hasOne(PostDescription::class);
    }

    public function comments()
    {
        return $this->hasMany(Comment::class);
    }

    public function labels()
    {
        return $this->belongsToMany(Label::class);
    }
}

class Comment extends Model
{
    use HasFactory;

    public $fillable = ['content'];

    public function post()
    {
        return $this->belongsTo(Post::class);
    }
}

class PostDescription extends Model
{
    use HasFactory;

    public function post()
    {
        return $this->belongsTo(Post::class);
    }
}

class Label extends Model
{
    use HasFactory;

    public function posts()
    {
        return $this->belongsToMany(Post::class);
    }
}

class LabelPost extends Model
{

}

일대일 관계

class PostTest extends TestCase
{
    use RefreshDatabase;

    public function testCanPostDescription()
    {
        // Given
        /** @var Post $post */
        $post = new Post();
        $post->title = "TEXT";
        $post->content = "HEHEH";
        $post->created_at = now();
        $post->save();

        /** @var Comment $comment */
        $description = new PostDescription();
        $description->content = "description";

        $description2 = new PostDescription();
        $description2->content = "description";

        $description->post()->associate($post);
        $description->save();

        // When
        $post->refresh();

        // Then
        $this->assertSame("TEXT", $post->title);
        $this->assertSame("description", $post->description->content);
    }

일대다

class PostTest extends TestCase
{
    use RefreshDatabase;

    public function testCanPostComment()
    {
        // Given
        /** @var Post $post */
        $post = new Post();
        $post->title = "TEXT";
        $post->content = "HEHEH";
        $post->created_at = now();
        $post->save();

        /** @var Comment $comment */
        $comment = new Comment();
        $comment->content = "comment content";
        $comment->post()->associate($post);
        $comment->save();

        // When
        $post->refresh();

        // Then
        $this->assertSame("TEXT", $post->title);
        $this->assertSame("comment content", $post->comments()->first()->content);
    }

다대다

class PostTest extends TestCase
{
    use RefreshDatabase;

    public function testCanCreatePostLabel()
    {
        // Given
        /** @var Post $post */
        $post = new Post();
        $post->title = "TEXT";
        $post->content = "HEHEH";
        $post->created_at = now();
        $post->save();

        /** @var Label $label */
        $label = new Label();
        $label->name = "name1";
        $label->save();
        $label->posts()->attach($post);

        $label2 = new Label();
        $label2->name = "name2";
        $label2->save();
        $label2->posts()->attach($post);


        // When
        $post->refresh();

        // Then
        $this->assertSame("TEXT", $post->title);
        $this->assertSame(2, count($post->labels()->get()));
    }

TODO

다형성 관계 및 라라벨 8에서 지원하는 관계들 추가

profile
unit test, tdd, bdd, laravel, django, android native, vuejs, react, embedded linux, typescript

0개의 댓글