I have this method which I use to filter result sets based upon a search query. As you can see, it will get the Fillable
elements from a model and search against those (possibly not that efficient, but it works and it's quite quick).
public static function searchAgainstFillable(&$query, $options, $useRelations = null){
// Get a list of fillable fields from the model
if($query->first() != null){
if(!$useRelations){
$fillables = $query->first()->getFillable();
// We could throw an exception here - but just in case oddities have occurred its
// probably best to just ignore an empty search term.
if(isset($options['search'])){
$results = $query->filter(function($setting) use($options, $query, $fillables){
foreach($fillables as $field){
if(stripos($setting->{$field}, $options['search']) !== false){
return true;
}
}
});
}
// Finally we want to overwrite the results passed in with the newly
// filtered results, ready to be presented in the response
$query = $results;
}
}
Unfortunately, I've since discovered that when using models that have many layers, this code will only work against the base table and not any other relations. Is there a way I can do this, without running a foreach
against every relational layer manually? Below is a snippet of my query.
{
"id": 1,
"created_at": "2015-05-18 15:10:59",
"updated_at": "2015-05-18 15:10:59",
"deleted_at": null,
"response_id": 10,
"user_id": 1,
"assigned_at": null,
"follow_up_step_num": 0,
"is_dropped_out": 0,
"assigned_user": {
"id": 1,
"created_at": "2015-05-15 13:18:22",
"updated_at": "2015-05-15 13:18:22",
"email": "REMOVED",
"firstname": "system",
"lastname": "user",
"location_id": 0,
"deleted_at": null,
"permissions": [],
"location_tags": []
},
"interactions": [
{
"id": 1,
"created_at": "2015-05-18 15:10:59",
"updated_at": "2015-05-18 15:10:59",
"deleted_at": null,
"closed_loop_interaction_type_id": 1,
"interaction_note": "Test Interaction note",
"closed_loop_processes_id": 1,
"interaction_type": {
"id": 1,
"created_at": "2015-05-18 15:10:59",
"updated_at": "2015-05-18 15:10:59",
"deleted_at": null,
"type": 0,
"method": "Phone Call (mobile)"
}
}
],
"response": [
{
"id": 10,
"created_at": "2015-02-20 18:48:07",
"updated_at": "2015-05-18 15:10:58",
"survey_request_id": 9,
"response": "Ullam mollitia explicabo accusamus ipsam ad in corrupti. Sed corrupti fugiat veritatis eaque accusantium non eaque deleniti. Doloremque rerum excepturi et adipisci. Et dicta corrupti omnis.",
"score": 8,
"deleted_at": null,
"survey_requests": null
}
]
}
Ideally, I want to be able to search against every model that's matched and against any fillable field they may contain.