Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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

Scroll Office Title
title일대다 관계

...

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

 

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

...

tinker 를 구동하고 다음과 같이 findOrFail() 메소드를 호출한 후에 tasks 프로퍼티를 호출합니다.

Code Block
>>> $tasks = App\Project::findOrFail(1)->tasks
>>> get_class($tasks)
=> "Illuminate\Database\Eloquent\Collection"

실행 결과를 확인해 보면 $tasks 변수의 타입은 "Illuminate\Database\Eloquent\Collection" 이며 project_id 가 1 인 App\Task 객체들을 담고 있는 것을 알 수 있습니다.

여기에서 중요한 점은 tasks() 가 아닌 tasks 로 사용해야 하는 점이며 라라벨은 PHP의 동적 프로퍼티(Dynamic Property) 기능을 사용하여 모델 간의 관계에 따라 객체들을 자동으로 가져오게 됩니다.

 

동적 프로퍼티는 사용이 쉽지만 다양한 조건으로 검색할 수 없으므로 만약 모델을 가져올 때 추가 검색 조건(예: name 컬럼으로 정렬)이 필요할 경우는 동적 프로퍼티가 아닌 메소드 호출을 하고 조건문을 추가 해야 합니다.

tinker 에서 다음과 같이 tasks() 를 호출하고 get_class()로 객체의 타입을 확인해 보면 $tasks 변수는 콜렉션이 아니라  Illuminate\Database\Eloquent\Relations 을 상속받은 HasMany 객체라는 것을 알 수 있습니다.

Code Block
>>>  $tasks = App\Project::findOrFail($id)->tasks()
>>> get_class($tasks)
=> "Illuminate\Database\Eloquent\Relations\HasMany"

 

Relations 객체는 내부에 Query Builder 를 내장하고 있으므로 다양한 쿼리 조건을 추가할 수 있으며 예로 project id 를 받아서 하위 task 를 name 항목으로 정렬하는 기능을 만들 경우 tasks() 호출후 orderBy 메소드를 추가 호출해 주면 됩니다.

테스트를 위해 아래의 코드를 Orm 컨트롤러의 getOneToMany() 메소드에 추가해 봅시다.

Code Block
public function getOneToMany($id)
{
	 // 
    $tasks = App\Project::findOrFail($id)->tasks()->orderBy('name')->get();
    dd($tasks);		
}
Warning

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

 

 

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

...