
worker:
label: '袨褌胁械褌褋褌胁械薪薪褘泄'
modelClass: Anplus\Andb\Models\Worker
conditions: worker_id in (:filtered)
nameFrom: fullName
public function getFullNameAttribute()
{
return $this->surname . ' ' . $this->name . ' ' . $this->patronymic;
}
@pavelmgn That's because the search applies a search query to the results which interfaces with the database layer, not a collection of models. Feel free to provide a PR to change this behavior.
Any updates on this? For now I'm using this but not ideal:
boot() {
Event::listen(
'backend.filter.extendQuery',
function ($filter, $query, $scope) {
if (post('scopeName', '') == 'user') {
$scope->nameFrom = 'name';
}
// Raise default query limit for long filters
$query->limit(100000);
}
);
}
@robinbonnes can't you achieve this with a scope method defined in your list model and specifying the scope method name in your list filter's scope option?
@robinbonnes can't you achieve this with a scope method defined in your list model and specifying the scope method name in your list filter's
scopeoption?
Thanks for your reply. I don't think I can, because the scope method seems to be for the filter result query and doesn't affect the search param? https://octobercms.com/docs/backend/lists#filter-scope-options
Will search for a workaround...
@robinbonnes but isn't that what you're trying to do (modify the filter result query) ?
@robinbonnes but isn't that what you're trying to do (modify the filter result query) ?
No scope function is like this:
public function scopeFromUser($query, $value)
{
return $query->whereHas(
'posts',
function ($q) use ($value) {
$q->whereIn('user_id', $value);
}
);
}
But we need to modify the search query, something like: concat(name, ' ', surname)
Any updates on this? For now I'm using this but not ideal:
boot() { Event::listen( 'backend.filter.extendQuery', function ($filter, $query, $scope) { if (post('scopeName', '') == 'user') { $scope->nameFrom = 'name'; } // Raise default query limit for long filters $query->limit(100000); } ); }
With this workaround I change the search query just before search, to search only on first name (name). But with this we can't search on surname.
In this way its working:
config_filter.yaml:
scopes:
user:
label: User
scope: fromUser
nameFrom: full_name
modelClass: RainLab\User\Models\User
Model:
public function scopeFromUser($query, $value)
{
return $query->whereHas(
'posts',
function ($q) use ($value) {
$q->whereIn('user_id', $value);
}
);
}
Plugin.php:
public function boot() {
Event::listen(
'backend.filter.extendQuery',
function ($filter, $query, $scope) {
if (post('scopeName', '') == 'user') {
$scope->nameFrom = 'concat(name, " ", surname)';
}
}
);
}
@robinbonnes you can achive the same with an accessor for full_name:
public function getFullNameAttribute()
{
return $this->name . " " . $this->surname;
}
And you won't need the backend.filter.extendQuery handler in your last example
@robinbonnes what exactly are you trying to do? Are you trying to make it so that a concatenated column result is included when list searches are run? In that case what I would recommend you do is that you add a new full_name column to columns.yaml that uses the select property, sets searchable: true and invisible: true. Now that column (even though it's not displayed) will be factored in when searching the list.
@LukeTowers this is for a list filter of type "group" which will show those result in a dropdown. He wants to show the concatenated values in the dropdown options.
@mjauvin @robinbonnes ah, in that case this is an easy problem to solve. Just specify the options property to a method that builds your options array however you want it to instead of using nameFrom.
I.e.
scopes:
user:
label: User
scope: fromUser
options: getUserOptions
modelClass: RainLab\User\Models\User
public function getUserOptions()
{
$users = static::select('id', 'first_name', 'last_name')->getQuery()->get(); // to get an array instead of models for large results
$result = [];
foreach ($users as $user) {
$result[$user['id']] = $user['first_name'] . ' ' . $user['last_name'];
}
}
@LukeTowers I don't see the benefit, the code is more complex for no gain. I find it better to create an accessor as I suggested.
@robinbonnes you can achive the same with an accessor for full_name:
public function getFullNameAttribute() { return $this->name . " " . $this->surname; }And you won't need the
backend.filter.extendQueryhandler in your last example
That exact same accessor is already there and it works when opening the dropdown, but not when searching inside the dropdown.
@mjauvin @robinbonnes ah, in that case this is an easy problem to solve. Just specify the
optionsproperty to a method that builds your options array however you want it to instead of using nameFrom.I.e.
scopes: user: label: User scope: fromUser options: getUserOptions modelClass: RainLab\User\Models\Userpublic function getUserOptions() { $users = static::select('id', 'first_name', 'last_name')->getQuery()->get(); // to get an array instead of models for large results $result = []; foreach ($users as $user) { $result[$user['id']] = $user['first_name'] . ' ' . $user['last_name']; } }
Didn't think about using the options parameter, thanks for that! Because User is a different plugin I'm using this solution for now, seems the cleanest:
public function boot()
{
User::extend(
function ($model) {
$model->addDynamicMethod(
'getUserOptions',
function () {
return User::select('id', DB::raw("CONCAT(name, ' ', surname) as full"))->orderBy('full')->lists('full', 'id');
}
);
}
);
}
@robinbonnes be aware that CONCAT() does not work with SQLite (maybe others) in case the Database need to be changed at some point.
@robinbonnes @mjauvin we have a selectConcat method in v1.1.1 that is cross-compatible - https://github.com/octobercms/library/pull/434.
Most helpful comment
@robinbonnes @mjauvin we have a
selectConcatmethod in v1.1.1 that is cross-compatible - https://github.com/octobercms/library/pull/434.