2016-10-12 1 views
2

Ich möchte eine Abfrage basierend auf optionalen Bedingung schreiben, die Daten aus verschiedenen Tabellen abrufen wird. Mein Schema sieht wieLaravel: Daten aus verschiedenen Tabellen basierend auf optionalen Bedingungen abrufen

myboxes Tabelle

id, 
type_id --> foreign key to box_type table 
postal_code 
po_box 
created_at 
updated_at 

mybox_access Tisch

id 
mybox_id -> foreign key to myboxes table 
email 

box_type Tisch

id 
type_name 

Und hier sind meine Modelle MyBox.php

class MyBox extends Model { 
    public function type() { 
     return this->hasOne(BoxType::class, 'id', 'type_id'); 
    } 

    public function access() id 
     return this->hasOne(MyBoxAccess::class, 'mybox_id', 'type_id'); 
    } 
} 

MyBoxType.php hat folgende Beziehung Schiff

public function mybox() { 
     return this->hasOne(MyBox::class, 'id', 'type_id'); 
    } 

Und MyBoxAccess.php hat folgende Beziehung

public function vbox() { 
     return $this->belongsTo(MyBox::class, 'id', 'mybox_id'); 
    } 

Jetzt will ich auf erhalten basierend folgende Bedingung Ich habe E-Mail nach Bedarf param und postal_code und po_box als optionale params (aber einer von ihnen wird muss und beide können auch vorhanden sein).

Deshalb mag ich Daten aller my_boxes erhalten, die type_id 3 oder alle myboxes whoes id in mybox_access Tabelle zu E-Mail Spiele und postal_code oder po_box in myboxes Tabelle params Spiele

Für einfaches Spiel von params Post Code und po_box Ich kann etwas wie

schreiben
$result = new MyBox(); 
if(!empty($request['postal_code'])) { 
    $result->where('postal_code', like, '%'.$request['postal_code']); 
} 
if(!empty($request['po_box'])) { 
    $result->where('po_box', like, '%'.$request['po_box']); 
} 
$result = $result->get(); 

Aber ich weiß nicht, wie man Daten für oben genannten Zustand erhalten. Wenn ich versuche, with() wie

MyBox::with(['access' => function(Builder $query) use ($request){ 
    $query->where('mybox_id',$request['id']); 
}])->get(); 

zu tun mit ich

`Argument 1 Passed to {closure}() must be an instance of Illuminat\Database\Query\Builder, instance of Illuminate\Databaase\Eloquent\Relation\HasOne given` 

Kann jede Stelle lassen Sie es mich wissen, wie kann ich Daten auf oben genannte Bedingung basiert bekommen

Antwort

1

$query ist eine Beziehung, keine Builder-Instanz.

Also das sollte keine Ausnahme werfen.

MyBox::with(['access' => function ($query) { 
    $query->where('mybox_id', $request['id']); 
}])->get(); 

Aber ich glaube nicht, dass Ihr Problem Resol würde, weil Ihre Box < => Zugriff Beziehung nicht stimmt. Es sollte HasMany sein.

// MyBox.php 
public function type() 
{ 
    return $this->hasOne(BoxType::class, 'id', 'type_id'); 
} 
public function access() 
{ 
    return $this->hasMany(MyBoxAccess::class, 'mybox_id', 'id'); 
} 

Dann in Ihrem Controller könnten Sie dies tun.

// $results where type_id is 3 
$results = MyBox::where('type_id', 3)->get(); 

// List of boxes accessible by email 
$results = MyBox::whereHas('access', function ($query) { 
    $query->where('email', request()->input('email')); 
})->get(); 

// Results where postal_code and po_box matches the request 
$results = MyBox::with('access')->where(function ($query) { 
    if (request()->has('postal_code')) { 
     $query->where('postal_code', 'like', '%' . request()->input('postal_code')); 
    } 
    if (request()->has('po_box')) { 
     $query->where('po_box', 'like', '%' . request()->input('po_box')); 
    } 
})->get(); 

Und wenn Sie alle Bedingungen zusammenführen möchten:

$results = MyBox::where(function ($query) { 
    if (request()->has('type_id')) { 
     $query->where('type_id', request()->input('type_id')); 
    } 
    if (request()->has('email')) { 
     $query->whereHas('access', function ($query) { 
      $query->where('email', request()->input('email')); 
     }); 
    } 
    if (request()->has('postal_code')) { 
     $query->where('postal_code', 'like', '%' . request()->input('postal_code')); 
    } 
    if (request()->has('po_box')) { 
     $query->where('po_box', 'like', '%' . request()->input('po_box')); 
    } 
})->get(); 

Ich benutze immer die request() Fassade, wenn in Schließungen mit, fühlt es sich für mich sauberer.

+0

Werde ich '-> get()' dreimal benutzen? –

+0

Nun, es kommt darauf an. Sie haben 3 verschiedene Arten von Ergebnissen gefragt (basierend auf type_id ODER email OR postal_code/po_box). Du könntest sicherlich nur 1 '-> get()' verwenden. – SimonDepelchin

+0

@SimponDepelchin gut Wie kann ich sie in einem kombinieren '-> get()' wie jedes Mal wird es eine Muss-Bedingung von Typ-ID und E-Mail und eine von Post_code oder po_box sein? wie where (type_id = 3 oder email = myemail) und (post_code = 12 oder po_box = 12)? –

0

Diese Abfrage:

+0

Und es wird lösen alle meine Fragen in Frage gestellt? –

Verwandte Themen