Reputation: 507
I currently have a shocking schema which I have inherited and due to eloquent not being able to filter against joined models I need to apply some filtering to the returned model + related models. Basically I have a movie object, which has a collection of malls where the movie is currently showing. I need to filter that collection where the "endDate" is >= today. No matter how I try and do this the model never seems to change. I can successfully filter the collection using array_filter, but I cannot assign it back to the model in any way? I return the whole model as a json object in a web service ( Response::json... )
I just want to know if this is at all possible or if i should bark up another tree? Here is a sample of the json data returned
{
"error": false,
"message": "Success",
"data": {
"movieID": "####",
"name": "The Grand Seduction",
"description": "The residents of a once-thriving Newfoundland coastal town are having trouble finding a way to make a living since the collapse of the fishing industry. They're thrilled when a plastics manufacturer proposes to set up shop until they find out the contract requires a resident doctor. \r\n\r\nThe villagers decide to woo Dr. Lewis (Taylor Kitsch), an ethically suspect cosmetic surgeon temporarily banished to the physician-starved seaside. Without revealing their plan, they take up the doctor's beloved sport of cricket, falling all over themselves in an effort to persuade him that their sleepy hamlet is loaded with cosmopolitan sophistication.",
"smallImage": "grand_seduction_small.jpg",
"length": "TBA",
"cast": "Anna Hopkins,BRENDAN GLEESON,Gordon Pinsent,Liane Balaban,Mark Critch,Matt Watts,Taylor Kitsch",
"director": "Don McKellar",
"producer": "Barbara Doran,Roger Frappier",
"ageRestriction": "TBA",
"genre": "Comedy",
"linkToSite": "",
"display": "Y",
"bigImage": "grand_seduction_large.jpg",
"threeD": "N",
"dateAdded": "2014-09-16 23:59:59",
"largeImage": "",
"YouTubeID": "",
"whatsshowing": [
{
"whatsShowingID": "####",
"mallID": "###",
"startDate": "2014-12-06 00:00:00",
"endDate": "2014-12-06 23:59:59",
"pivot": {
"movieID": "####",
"whatsShowingID": "#####",
"times": "09:00; 11:30; 14:00; 22:45; ",
"featured": "",
"finalWeek": "N"
}
},
{
"whatsShowingID": "####",
"mallID": "###",
"startDate": "2014-11-29 00:00:00",
"endDate": "2014-11-29 23:59:59",
"pivot": {
"movieID": "####",
"whatsShowingID": "####",
"times": "09:00; 14:15; 19:30; ",
"featured": "",
"finalWeek": "N"
}
},...........
As you can see, I get back 1 movie and then a collection of "whatsshowing" objects and would like to remove any of them that have an endDate less than today.
Here is a snippet of controller code to explain what I am doing currently
$query = MovieModel::query();
$query = $query->with('whatsshowing');
$data = $query->findOrFail($id);
//filter out what I dont want
$new = array_filter($data->whatsshowing->toArray(), function($obj){
if (isset($obj["endDate"])) {
if ($obj["endDate"] >= '2014-12-14')
return true;
}
return false;
});
//assign the data back to the object
data->whatsshowing = $new;
//?????? nothing changes??
Could it be that the property is protected? I haven't a clue and am ready to throw this pc through the wall...
Please bear in mind I am a C# developer with a grand total of 4 months PHP experience so please be gentle...
Upvotes: 1
Views: 1018
Reputation: 81167
eloquent not being able to filter against joined models - this is basically wrong.
You want eager load constraints:
MovieModel::with(['whatsshowing' => function ($q) {
$q->where('endDate', '>=', DB::raw('curdate()'));
}])->findOrFail($id);
Obviously DB::raw('curdate()')
piece can be replaced with eg. Carbon::today()
, date('Y-m-d')
and so on.
Upvotes: 2
Reputation: 152890
$data->setRelation('whatsshowing', $new);
However $new
needs to be a Collection, so do this:
$new = $data->whatsshowing->filter(function($obj){
if($obj->endDate >= '2014-12-14'){
return true;
}
return false;
});
$data->setRelation('whatsshowing', $new);
The problem is, the relations of results are stored inside a relations
array on the model (and not just as properties). When you call Response::json
(resulting in ->toJson()
on the model), Laravel ignores the property you added and uses the value from relations[]
.
What setRelation()
does? It just stores the value inside the relations
array.
Upvotes: 0