Ich entwickle eine Web-API mit Laravel 5.0, bin mir jedoch nicht sicher, welche Abfrage ich erstellen möchte.
Meine Klassen sind wie folgt:
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');
}
}
und
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');
}
}
Jetzt möchte ich alle Veranstaltungen mit einem bestimmten Teilnehmer erhalten. Ich habe versucht mit:
Event::with('participants')->where('IDUser', 1)->get();
aber die where
Bedingung wird auf die Event
und nicht auf ihre angewendet Participants
. Folgendes gibt mir eine Ausnahme:
Participant::where('IDUser', 1)->event()->get();
Ich weiß, dass ich das schreiben kann:
$list = Participant::where('IDUser', 1)->get();
for($item in $list) {
$event = $item->event;
// ... other code ...
}
Es scheint jedoch nicht sehr effizient zu sein, so viele Anfragen an den Server zu senden.
Was ist der beste Weg, um where
mit Laravel 5 und Eloquent eine Modellbeziehung durchzuführen ?
Antworten:
Die richtige Syntax für Ihre Beziehungen lautet:
Event::whereHas('participants', function ($query) { return $query->where('IDUser', '=', 1); })->get();
Lesen Sie mehr unter https://laravel.com/docs/5.8/eloquent-relationships#eager-loading
quelle
Die Antwort von @ Cermbo bezieht sich nicht auf diese Frage. In ihrer Antwort wird Laravel Sie alle geben ,
Events
wenn jederEvent
hat'participants'
mitIdUser
der1
.Aber wenn Sie alles
Events
mit allem bekommen wollen,'participants'
vorausgesetzt, alle'participants'
haben eineIdUser
1, dann sollten Sie so etwas tun:Event::with(["participants" => function($q){ $q->where('participants.IdUser', '=', 1); }])
NB:
in
where
Gebrauch Ihre Tabellennamen, nicht Modellname.quelle
Verwenden Sie bei mehreren Verknüpfungen etwa den folgenden Code:
Event::with(["owner", "participants" => function($q) use($someId){ $q->where('participants.IdUser', '=', 1); //$q->where('some other field', $someId); }])
quelle
return Deal::with(["redeem" => function($q){ $q->where('user_id', '=', 1); }])->get();
das hat bei mir funktioniert
quelle
Ich habe in BaseModel einen benutzerdefinierten Abfragebereich erstellt (alle Modelle erweitern diese Klasse):
/** * 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); }); }
Sie können es in vielen Kontexten verwenden, zum Beispiel:
Event::whereHasRelated('participants', 1)->isNotEmpty(); // where has participant with id = 1
Außerdem können Sie versuchen, den Beziehungsnamen wegzulassen und nur das Modell zu übergeben:
$participant = Participant::find(1); Event::whereHasRelated($participant)->first(); // guess relationship based on class name and get id from model instance
quelle
[OOT]
Ein bisschen OOT, aber diese Frage ist das Thema, das meiner Frage am nächsten kommt.
Hier ist ein Beispiel, wenn Sie ein Ereignis anzeigen möchten, bei dem ALLE Teilnehmer bestimmte Anforderungen erfüllen. Angenommen, eine Veranstaltung, bei der ALLE Teilnehmer vollständig bezahlt haben . Es werden also KEINE Ereignisse zurückgegeben, bei denen ein oder mehrere Teilnehmer nicht vollständig bezahlt haben.
Verwenden Sie einfach den
whereDoesntHave
Status der anderen 2.Nehmen wir an, die Status werden überhaupt nicht bezahlt [Gleichung: 1], haben einen Teil davon bezahlt [Gleichung: 2] und sind voll bezahlt [Gleichung: 3]
Event::whereDoesntHave('participants', function ($query) { return $query->whereRaw('payment = 1 or payment = 2'); })->get();
Getestet auf Laravel 5.8 - 7.x.
quelle
Event::with(['participants, avenue])