source

Laravel where 관계 객체

factcode 2022. 9. 21. 23:23
반응형

Laravel where 관계 객체

저는 Larabel 5.0으로 웹 API를 개발 중인데 제가 구축하려는 특정 쿼리에 대해서는 잘 모르겠습니다.

제 수업은 다음과 같습니다.

class Event extends Model {

    protected $table = 'events';
    public $timestamps = false;

    public function participants()
    {
        return $this->hasMany('App\Participant', 'IDEvent', 'ID');
    }

    public function owner()
    {
        return $this->hasOne('App\User', 'ID', 'IDOwner');
    }
}

그리고.

class Participant extends Model {

    protected $table = 'participants';
    public $timestamps = false;

    public function user()
    {
        return $this->belongTo('App\User', 'IDUser', 'ID');
    }

    public function event()
    {
        return $this->belongTo('App\Event', 'IDEvent', 'ID');
    }
}

이제 특정 참가자와 모든 이벤트를 받고 싶습니다.시도 대상:

Event::with('participants')->where('IDUser', 1)->get();

하지만where조건이 에 적용됩니다.Event그 위에 있지 않다Participants예외는 다음과 같습니다.

Participant::where('IDUser', 1)->event()->get();

나는 내가 이것을 쓸 수 있다는 것을 안다.

$list = Participant::where('IDUser', 1)->get();
for($item in $list) {
   $event = $item->event;
   // ... other code ...
}

서버에 많은 쿼리를 보내는 것은 그다지 효율적이지 않은 것 같습니다.

어떻게 하면 가장 좋은 방법으로where라라벨 5와 웅변가를 사용한 모델 관계를 통해요?

관계에서 이를 수행하기 위한 올바른 구문은 다음과 같습니다.

Event::whereHas('participants', function ($query) {
    return $query->where('IDUser', '=', 1);
})->get();

그러면 참가자의 사용자 ID가 1인 이벤트가 반환됩니다.참가자의 사용자 ID가 1인 경우, 이벤트는 반환되지 않습니다.

자세한 것은, https://laravel.com/docs/5.8/eloquent-relationships#eager-loading 를 참조해 주세요.

@Cermbo의 답변은 이 질문과는 관련이 없습니다.그 대답에서Laravel다 줄게Events만약 각각이Event가지다'participants'와 함께IdUser1.

하지만 당신이 모든 것을 얻고 싶다면Events모두와 함께'participants'그 모든 것이 다라면'participants'을 가지고 있다IdUser1 의 경우는, 다음과 같은 조작을 실시합니다.

Event::with(["participants" => function($q){
    $q->where('participants.IdUser', '=', 1);
}])

주의:

에서where모델 이름이 아닌 테이블 이름을 사용합니다.

라라벨 8.57+용

Event::whereRelation('participants', 'IDUser', '=', 1)->get();

여러 조인을 사용하는 경우 다음과 같은 코드를 사용합니다.

$userId = 44;
Event::with(["owner", "participants" => function($q) use($userId ){
    $q->where('participants.IdUser', '=', 1);
    //$q->where('some other field', $userId );
}])

다음 코드 사용:

return Deal::with(["redeem" => function($q){
    $q->where('user_id', '=', 1);
}])->get();

라라벨 8은 이것을 대신 사용한다.

Event::whereHas('participants', function ($query) {
     $query->where('user_id', '=', 1);
})->get();

사용자 ID가 1인 partcipat과 해당 이벤트 재연결이 있는 경우에만 이벤트가 반환됩니다.

BaseModel에서 사용자 지정 쿼리 범위를 만들었습니다(모든 모델에서 이 클래스를 확장함).

/**
 * Add a relationship exists condition (BelongsTo).
 *
 * @param  Builder        $query
 * @param  string|Model   $relation   Relation string name or you can try pass directly model and method will try guess relationship
 * @param  mixed          $modelOrKey
 * @return Builder|static
 */
public function scopeWhereHasRelated(Builder $query, $relation, $modelOrKey = null)
{
    if ($relation instanceof Model && $modelOrKey === null) {
        $modelOrKey = $relation;
        $relation   = Str::camel(class_basename($relation));
    }

    return $query->whereHas($relation, static function (Builder $query) use ($modelOrKey) {
        return $query->whereKey($modelOrKey instanceof Model ? $modelOrKey->getKey() : $modelOrKey);
    });
}

다음과 같은 다양한 컨텍스트에서 사용할 수 있습니다.

Event::whereHasRelated('participants', 1)->isNotEmpty(); // where has participant with id = 1 

또한 관계 이름을 생략하고 모델만 전달할 수 있습니다.

$participant = Participant::find(1);
Event::whereHasRelated($participant)->first(); // guess relationship based on class name and get id from model instance

[앗]

약간 헛소리지만 이 질문이 제 질문과 가장 가까운 주제입니다.

다음으로 모든 참가자가 특정 요건을 충족하는 이벤트를 표시하는 예를 나타냅니다.예를 들어, 모든 참가자가 전액 지불한 이벤트입니다.따라서, 한 명 이상의 참가자가 전액 지불하지 않은 이벤트는 반환하지 않을 것입니다.

를 사용하면 됩니다.whereDoesntHave다른 2가지 상태 중 하나.

상태가 전혀 지불되지 않고 [eq:1]의 일부를 지불하고 [eq:2]를 완전히 지불했다고 합니다.

Event::whereDoesntHave('participants', function ($query) {
   return $query->whereRaw('payment = 1 or payment = 2');
})->get();

Larabel 5.8 - 7.x에서 테스트 완료

언급URL : https://stackoverflow.com/questions/29989908/laravel-where-on-relationship-object

반응형