2016-12-29 4 views
2

Laravel 5.3에서 첫 번째 다형성 관계에 대해 머리를 쓰려고합니다.Laravel 5.3 다형성 관계

내가 맺으려는 관계는 'Editorial'에 많은 'Elements'가있을 것이며, 각 요소는 각자의 모델이되고 주문을 받게된다는 것입니다.

예를 들어, 'ElementText', 'ElementImage', 'ElementButton'모델을 사용하게되면 'Editorial'에 다양한 요소가 할당됩니다.

이것은 내가 왜 내가 다형성 관계가 필요하다고 생각합니다. 나는 'Editorial'모델의 각 요소 유형에 대해 여러 관계를 원하지 않습니다. 유형에 관계없이 모든 '요소'를 가져 와서 순서대로 가져올 수 있기를 바랍니다.

내가 생각 솔루션은 laravel 워드 프로세서에서 morphToMany 예와 유사

editorial_id - integer 
order - integer 
element_id - integer 
element_type - string 

처럼 열이있는 'editorial_element'피벗 테이블을 가지고있을 거라고 생각하지만 예를 들어 당신이에 모델을 지정해야 morph.

그래서 내 사설 모델에서 morphTo() 메서드를 사용해야하는지 궁금합니다.

public function elements() { 
    return $this->morphTo(); 
} 

하지만 난 그게 내가 뒤로

는 내가 필요로하는 관계를 어떤 생각을 설정할 수있는 경우 (사설 당 하나 개의 요소를 허용하는) 것입니다 내 사설 테이블에 _type_id 열을 추가해야 할 것입니다 의미한다고 생각 내가 잘못 접근하고 있는가?

답변

1

다형성 관계가 여기에 잘 맞지 않을 것이라고 생각합니다. 그렇게 접근 할 수 있습니다.

editorials 
- id 
- title 
- etc... 

elements 
- editorial_id 
- elements_id 
- elements_type 

elements_image 
- id 
- url 

elements_text 
- id 
- text 

그러면 모델이 될 수 있습니다.

class Editorial extends Model { 

    // ... 

    public function elements() { 
     return $this->hasMany(\Element::class); 
    } 

    // ... 

} 

class Element extends Model { 

    // ... 

    public function editorial() { 
     return $this->belongsTo(\Editorial::class); 
    } 

    public function image() { 
     return $this->belongsTo(\ElementImage::class, 'elements_id'); 
    } 

    public function text() { 
     return $this->belongsTo(\ElementText::class, 'elements_id'); 
    } 

    public function content() { 
     $type = $this->elements_type; 
     return $this->{$type}(); 
    } 

    // ... 

} 

class ElementImage extends Model { 

    // ... 

    public function element() { 
     return $this->hasOne(\Element::class, 'elements_id'); 
    } 

    // ... 

} 

class ElementText extends Model { 

    // ... 

    public function element() { 
     return $this->hasOne(\Element::class, 'elements_id'); 
    } 

    // ... 

} 

아마도 당신은 모든 요소에 render() 방법을 강제하는 인터페이스를 구현하는 모든 요소를 ​​만들 수있는 다음 뷰에서이 작업을 수행 할 수 있습니다 :

@foreach($editorial->elements as $element) 
    {{ $element->content->render() }} 
@endforeach 

렌더 방법은 다음에 대한 책임을 질 수 있습니다 콘텐츠를 포맷하고 출력하는 것.

이것은 모두 이론에 불과합니다. 이전에 시도한 문제이기 때문에이 문제를 해결할 수 있는지 궁금 할 것입니다. 어떤 수정 사항이 있었는지 또는 제 생각이 바보 같다고 생각한다면 알려주십시오.

+0

알다시피, '요소'모델을 수동으로 업데이트해야하며 더 이상 attach(), detach() 메소드를 사용하지 않을 것이라고 생각합니다. –

+0

'BelongsTo()'는'associate()'와'disassociate()'을 가지고 있지만, 일단 당신이 그것들을 생성하면 관계를 조작 할 상황을 생각할 수 없습니다. 변경 사항을 볼 수있는 단 하나는'Editorial - hasMany - Element'이고, 불행히도 거기에는'sync()'메소드가없는 것 같지만'saveMany()'할 수 있습니다. –

+0

일찍부터 집으로 보내지기 전에이 접근법에 빨리갔습니다. 나는보기를 사용하지 않았지만 다음을 수행했습니다. $ editorial = \ App \ Editorials :: with ('elements') -> first(); foreach ($ editorial-> 요소를 & $ 요소로) { \t \t $ 요소 -> 내용; \t}. 궁금한 점이 성능에 어떤 영향을 미치는지 .. –

0

다음과 같이 관계를 설정해야합니다.

Editorial 모델에는 변형 된 각 Element* 모델에 대한 메소드가 있어야합니다. 예 : 당신의 Element* 모델에서

public function textElements() { 
    return $this->morphedByMany(ElementText::class, 'element'); 
} 


public function buttonElements() { 
    return $this->morphedByMany(ElementButton::class, 'element'); 
} 

당신은에 변신있어 모든 Editorials를 얻기 위해 아래의 방법이 있어야합니다.

public function editorials() 
    return $this->morphToMany(Editorial::class, 'element'); 
} 

참고 : 주목할 가치가 그 다형성 관계를 사용하여 몇 가지 문제가 있습니다. 가장 중요한 것은 데이터베이스 구조에서 단순함을 얻지 만 동시에 외래 키 제약 조건을 잃는 것입니다. 즉, Element*이 삭제되면 수동으로 변형 된 Editorials을 삭제해야합니다. 보통 Many to Many 관계에서는 외래 키 제약 조건을 설정할 수 있으며 RDBMS는이를 자동으로 처리합니다.

참고 2 : 먼저 요소 테이블을 단일 테이블로 통합 할 수 있는지 확인하려고합니다. 그들이 할 수 있다면 당신의 일은 훨씬 쉬워 질 것입니다. 그러나 많은 요소 테이블을 사용해야하는 경우 두 가지 방법이 모두 좋다고 생각합니다. 각각에는 이점과 단점이 있습니다. 이것은 많은 관계 테이블 또는 다형성 관계로 데이터베이스 일관성을 직접 처리해야하며 어느 방법이든 관계를 통해 $editorial->elements()을 수행 할 수 없습니다.

+0

그래서 유일한 해결책은 사설 모델의 각 요소 유형에 대해 여러 관계를 갖는 것이라고 생각하십니까? 이상적으로 나는 단지 그들 모두를 가져 오는 하나의 "요소"관계를 원합니다. –

+1

@VinceLowe 내 대답을 편집했습니다. 메모 읽기 2 –

+0

@ FarzinFarzanehnia 이봐, 내 대답을 확인해 주시겠습니까? 그냥 당신의 생각을보고 호기심. –