모델

2017-10-25 1 views
1

을 반환하는 범위 유사 함수 this question에 대한 대답은 모델 범위가 쿼리 작성기 인스턴스를 반환하는 것이 아니며 사용자 지정 getter를 사용하여 모델 인스턴스를 반환해야 함을 설명합니다. 내 경우모델

문제

나는 사용자가 많은 계약이있는 UserContract 모델을 보유하고 있습니다. 계약 기간은 중복 될 수 있지만 주어진 시간에 최신 시작 날짜의 계약 만 유효하다고 간주되어야합니다 (예 : 계약 1을 2017-01-01에서 2017-07-31으로, 계약 2를 2017-06-01에서 2017-12-31까지 2017-07-01 계약 2를 반환해야 함)

현재 솔루션

난 항상 ->first() 전화를해야 범위를 사용 :

public function scopeByDate(Builder $query, $date) { 
    return $query->whereDate('start', '<=', $date) 
       ->whereDate('end', '>=', $date) 
       ->orderBy('start', 'desc'); 
} 
public function scopeCurrent(Builder $query) { 
    return $this->scopeByDate($query, date('Y-m-d')); 
} 
... 
$user->contracts()->byDate('some-date')->first(); 
$user->contracts()->current()->first(); 

(가 나쁜?) 다른 솔루션

그렇지 않으면 나는 중 하나 Builder이 (나에게 나쁜 모양) 또는 User (더 악화?) 인스턴스를 받아, byDate()current() 정적 만들 수있는 수동

public static function byDate(Builder $query, $date) { 
    return $query->whereDate(...)->whereDate(...)->orderBy(...)->first(); 
} 
... 
Contract::byDate($user->contracts(), 'some-date'); 
같은 매개 변수를 전달

또는

public static function byUserAndDate(User $user, $date) { 
    return $user->contracts()->where...->where...->orderBy(...)->first() 
} 
... 
Contract::byUserAndDate($user, 'some-date'); 

질문

추가 매개 변수를 전달하지 않고 쿼리 작성기 (관계)에서 직접 호출하여 을 호출해야하는 경우가 있습니다.

+2

사용자가 다음과 같은 메소드를 생성하지 않는 이유는 무엇입니까? public function currentContract() { return $ this-> contracts() -> current() -> first(); }'당신이 할 일은'$ user-> currentContract()'입니다 !! – Maraboc

+0

@Maraboc은 다음과 같이 말합니다. 그 논리를 방법으로 포장하십시오. Laravel에는 접근 자, 변형 자, 범위 등과 같은 멋진 요소가 있지만 모든 시나리오에 사용할 수는 없습니다. – ingkevin

+0

그 경우 @ingkevin에 대한 답을 추가했습니다. 그냥 제안 이었지만 사람들이 좋아할 때 대답으로 만들지 마십시오.) – Maraboc

답변

1

당신은 사용자 모델의 메소드 내부의 논리를 포장 할 경우에 당신이 ->first() 할 필요없이 필요하면 다음 전화 :

사용자 모델

public function currentContract() { 
    return $this->contracts()->current()->first(); 
} 

public function contractByDate($date) { 
    return $this->contracts()->byDate($date)->first(); 
} 

그리고 통화 :

$user->contractByDate('some-date'); 
$user->currentContract(); 

친절하고 깨끗한 :

+0

User 모델의 함수에 wheres를 넣음으로써 거의 같은 아이디어를 가졌습니다. 나에게 커플.Wheres를 계약 범위에 넣고 사용자의 방법으로 액세스하는 것은 "멋지고 깨끗합니다"라고 느끼게하고 나는 조금 어리 석 게 느낍니다. 이 힌트를 가져 주셔서 감사합니다 :) –

+0

도와 드리겠습니다;) – Maraboc