问题
I have a problem with get data only when relation query count is more than 0.
This is my model of customer with relation
class Customer extends Model
{
protected $table = 'customers';
public function contracts()
{
return $this->hasMany('App\Contract');
}
This is my model of contracts
class Contract extends Model
{
public function customer()
{
return $this->belongsTo('App\Customer');
}
}
On the end i need only customers who they contracts beetwen some date
$customers = Customer::with(['contracts' => function($query)
{
$query->where('data_end','>=','2017-07-01')
->where('data_end','<=','2017-07-31')
->where('typ','=','U') ;
}
])->paginate(10);
But i have all customers. and it looks like this:
"Customer 1"
"Customer 2"
"Customer 3"
*"Contract 1"
*"Contract 2"
*"Contract 3"
"Customer 4"
*"Contract 1"
*"Contract 2"
*"Contract 3"
"Customer 4"
In this example i don't need customer 1,2, and 5. How can i do it with eager loading and object with relation on the end.
enter image description here
This is happen, i dont need customer with X on the screenshot - I mean, I don't need customer with 0 contracts from where query
-- Object from dd()--
end of this query 2 customer, 1st have 2 contracts, 2nd have 0 contracts
LengthAwarePaginator {#217 ▼
#total: 75000
#lastPage: 37500
#items: Collection {#213 ▼
#items: array:2 [▼
0 => Customer {#220 ▼
#table: "customers"
#connection: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:5 [▼
"id" => 1
"customer_number" => "46071600600"
"name" => "Nikodem Zalewski"
"customer_contact" => "507614445"
"customer_type" => "P"
]
#original: array:5 [▶]
#casts: []
#dates: []
#dateFormat: null
#appends: []
#events: []
#observables: []
#relations: array:1 [▼
"contracts" => Collection {#224 ▼
#items: array:2 [▼
0 => Contract {#227 ▼
#connection: null
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:10 [▶]
#original: array:10 [▶]
#casts: []
#dates: []
#dateFormat: null
#appends: []
#events: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
1 => Contract {#229 ▶}
]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
1 => Customer {#221 ▼
#table: "customers"
#connection: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:5 [▶]
#original: array:5 [▼
"id" => 2
"customer_number" => "81050371854"
"name" => "Adam Wróbel"
"customer_contact" => "560047958"
"customer_type" => "P"
]
#casts: []
#dates: []
#dateFormat: null
#appends: []
#events: []
#observables: []
#relations: array:1 [▼
"contracts" => Collection {#222 ▼
#items: []
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
]
}
#perPage: 2
#currentPage: 1
#path: "*"
#query: []
#fragment: null
#pageName: "page"
}
回答1:
You are almost there with your code.
You don't specify which version of Laravel you're using, but you should be looking at whereHas (This exists in Laravel since at least 5.0)
https://laravel.com/docs/5.0/eloquent#querying-relations (v5.0)
When accessing the records for a model, you may wish to limit your results based on the existence of a relationship. For example, you wish to pull all blog posts that have at least one comment. To do so, you may use the has method:
If you need even more power, you may use the whereHas and orWhereHas methods to put "where" conditions on your has queries:
Try the following code.
$customers = Customer::with('contracts')->whereHas('contracts', function($query)
{
$query->where('data_end','>=','2017-07-01')
->where('data_end','<=','2017-07-31')
->where('typ','=','U') ;
}
)->paginate(10);
This will load the contracts object with customers but only return customers who have contracts matching the query.
来源:https://stackoverflow.com/questions/45355201/get-object-only-when-relation-result-is-exist-laravel