[Model] 같은 형태에 대한 여러개의 테이블이 존재할 때, 1개의 Model로 사용하기 version 1.0

최근 라라벨을 사용하여 API를 만드는 작업을 진행하던 중, 같은 Database 내부에서 사용되는 table이 아래와 같은 경우가 생겼습니다.

상품 관련 테이블 : A_Products , B_Products, C_Products 
주문 관련 테이블 : A_Orders, B_Orders, C_Orders
.....
.....
.....

라라벨에서 table에 따른 Eloquent model을 만들 때 지향하는 것은 [App/Models/] 하위에 아래와 같이 model을 각각 생성하겠죠.

$ php artisan make:model AProject;
$ php artisan make:model BProject;
$ php artisan make:model CProject;

$ php artisan make:model AOrder;
$ php artisan make:model BOrder;
$ php artisan make:model COrder;

하지만 앞의 1글자만 다르고, 모든 테이블 컬럼 구성이 같은데 구지 '일일이 그에맞는 모델을 생성하여 관계를 형성시키는건 코드관리에 있어서 효율적이지 못하다' 라고 저는 생각이 들었습니다. 때문에 Project, Order 각각 1개의 Model을 만든 후 각 Model을 상황에 맞게 유동적으로 바인딩 시킬 수 있는 방법이 있을까? 하는 의문을 가지기 시작했습니다.


1. Product Model을 아래와 같이 생성합니다.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;
    
    protected $connection = "yourDB";
    const TABLE = "_Products";
    
    public function setTableName($tableName)
    {
        $this->table = $tableName.self::TABLE;
    }
}

 

2. Order Model을 아래와 같이 생성합니다.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    use HasFactory;

    protected $connection = "yourDB";
    const TABLE = "_orders";
    
    public function setTableName($tableName)
    {
        $this->table = $tableName.self::TABLE;
    }
}

 

3. Controller에서 동적으로 테이블을 바꾸며 사용하는 법

/**
*  your controller.php
*/

// Product 모델 정의
$productModel = new Product;
$productModel->setTableName("A"); // A_Products Table 사용하다가
$productModel->setTableName("B"); // B_Products Table 사용하고 싶으면 변경
$productModel->setTableName("C"); // C_Products Table 사용하고 싶으면 변경


// Order 모델 정의
$orderModel = new Order;
$orderModel->setTableName("A"); // A_Orders Table 사용하다가
$orderModel->setTableName("B"); // B_Orders Table 사용하고 싶으면 변경
$orderModel->setTableName("C"); // C_Orders Table 사용하고 싶으면 변경

 

4. Eloquent ORM Relationship은 사용할 수 없음.

각 테이블에 맞는 맵핑된 모델을 1개씩 만들어 연관성을 쉽게 표현하게 해주는 Laravel Eloquent ORM의 RelationShip은 위 방법으로는 사용할 수 없다. 때문에 위의 방법을 사용하여 동적 바인딩을 할 경우, 라라벨 쿼리빌더를 사용하여 데이터를 이용한다.

 

5. 추가사항

Eloquent ORM Relations을 사용 가능하게 하는 방법을 탐구하였고, 해답을 찾아내어 아래와 같이 포스팅하였음.

 

[Model] 같은 형태에 대한 여러개의 테이블이 존재할 때, 1개의 Model로 사용하기 version 2.0

이전에 하나의 DB 스키마 아래에 테이블 앞에 글자만 다르고, 모든 형태가 일치(칼럼, 키, 색인 등 모든 게 일치)하는 경우에 Laravel Model에서 1개의 Model로 여러 테이블에 동적으로 바인딩해서 사용

min-nine.tistory.com