In my Setting
model. I have a local scope
that accepts $data
array argument. The $data
contains two keys group
and property
and any of them can be null as you can see in my query.
public function scopeSettingFilters($query, array $data)
{
$query->when(!empty($data['group']), fn($q) => $q->where("group", $data["group"]));
$query->when(!empty($data['property']), function ($q) use ($data) {
$property = $data['property'];
if (str_contains($property, '.')) {
[$group, $property] = $this->splitKey($data['property']);
$q->where(["group" => $group, "name" => $property]);
} else {
$q->where("name", $property);
}
});
return $query;
}
Now I want to convert $data
array keys to Named Arguments for better code understanding and one major reason for conversion is, that currently the group
is accepting only string
but now it is either a string
or array
.
My Setting Table
id | user_id | group | property | value |
---|---|---|---|---|
1 | 1 | notifications | event_email | true |
1 | 1 | onboarding | welcome_video_watched | false |
Note: I’m using
Laravel 9
Version
Expected Syntax:
After making the required changes I would able to call Laravel query scope
using named argument
something like that:
Setting::settingFilters(group: "onboarding")->get() //filter single group
Setting::settingFilters(group: ["onboarding", "notifications"])->get() //filter multiple groups
2
Answers
I had fixed it using following code:
If you want to refactor your code to use named arguments, you can change the function signature of scopeSettingFilters to accept named arguments instead of a single $data array. You can set default values for the arguments to null to make them optional.
Here’s an example that shows how you could refactor your code:
Key changes:
The function now accepts named arguments $group and $property, both of which have default values set to null.
Inside the lambda function for the when() method, I’ve added a check for $group being an array. If it is an array, it uses whereIn to filter by multiple group names; otherwise, it uses where as you did before.
Now you can call this scope with named arguments like so: