Page tree

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 13 Next »

일대다 관계는 가장 일반적인 관계의 종류로 테이블 A의 한 모델은 테이블 B의 여러 모델과 일치할 수 있지만 테이블 B의 한 모델은 테이블 A의 한 모델과만 일치할 수 있습니다.

예를 들어, Projects 테이블의 한 프로젝트는 Tasks 테이블의 여러 개의 task 를 가질 수 있지만 task 는 하나의 프로젝트밖에 가질 수 없습니다.getHasMany

일대다 관계

 

일대다 관계를 정의하려면 일대일과 마찬가지로 부모가 되는 모델에 자식의 테이블명과 일치하는 메소드를 만들고 hasMany($related, $foreignKey = null, $localKey = null) 를 사용하여 자식 모델을 기술해 주면 되며 필수인 첫 번째 파라미터는 관련된 테이블 모델명입니다.

class Project extends Model
{
    public function tasks()
    {
        return $this->hasMany(Task::class);
    }
}

만약 참조 키 이름은 다음과 같은 로직에 의해서 결정되며 정확한 참조 키 이름을 알고 싶으면 다음 코드를 artisan tinker 에서 돌려서 알아 낼 수 있습니다. 

>>> snake_case(class_basename('App\ArticleCategory')).'_id';             
=> "article_category_id"

 참조 키 이름이  관례와 다를 경우 두 번째 파라미터로 명시적인 참조키 이름을 지정해 주면 됩니다.

 

Tasks 테이블은 belongsTo($related, $foreignKey = null, $otherKey = null, $relation = null) 메소드를 사용하여 첫 번째 파라미터로 부모 모델 클래스를 지정해 줍니다.

class Task extends Model
{
    public function project()
    {
        return $this->belongsTo(Project::class);
    }
}

Eloquent ORM 은 관계가 지정된 컬럼명을 관례에 따라 snake case 명명법으로 참조모델명_id 로 찾으므로 Task 모델의 프로젝트 테이블에 대한 참조키는 project_id 가 되며 만약 레거시 테이블이라 관례에 따라 작명되지 않았다면 hasMany() 나 belongsTo()의 두번째 파라미터에 해당 컬럼명을 지정해 주면 됩니다.

다음은 Tasks 테이블의 Projects 테이블에 대한 참조키 이름이 project_fk_name 일 경우 관계를 정의하는 예제입니다.

class Task extends Model
{
    public function project()
    {
        return $this->belongsTo(Project::class, 'project_fk_name');
    }
}

 

이제 테스트를 위해 Orm 컨트롤러에 getOneToMany() 메소드에 검색 조건을 구현합니다. 이 예제에서는 프로젝트에 속하는 tasks 를 가져와서 이름을 기준으로 정렬합니다.

public function getOneToMany($id)
{
    $tasks = Project::findOrFail($id)->tasks->orderBy('name')->get();
    dd($tasks);		
}

Eloquent 는 동적 프로퍼티를 사용하여 관련된 모델을 가져오므로 Project::find(7)->tasks() 처럼 메소드로 사용하면 안 되며 Project::find(7)->tasks 처럼 프로퍼티로 사용해야 제대로 동작합니다.

 

브라우저로  http://homestead.app/orm/one-to-many/3 에 연결해 보면 일대다 관계이므로 여러 개의 자식 모델을 가져온 것을 알 수 있습니다.

일대다 검색 결과

 

만약 Task 의 부모 모델을 찾으려면 다음과 같이 Task 모델의 project 메소드를 호출하면 됩니다.

>>> App\Task::find(1)->project
=> <App\Project #0000000002558acd00000000675df7f7> {
       id: 1,
       user_id: 1,
       name: "개인",
       is_public: 0,
       created_at: "2015-07-25 00:26:57",
       updated_at: "2015-07-25 00:26:57"
   }