I have a problem with Laravel Voyager v1.2. I need to filter list of related list of options in select dropdown easily by where condition. So let's say I have Post with relation to Category, but I don't want to list all Categories in select dropdown, but just that active ones.
public function category_id() {
return $this->belongsTo('Post::class')->where('active',1);
}
{
"relationship": {
"key": "id",
"label": "name",
"scopes": [
"active"
]
}
}
Post Model part:
public function scopeActive($query) {
return $query->where('active', 1);
}
This is how my Post class look like (I don't actualy need to filter active categories, but food categories by it's IDs):
public function soup1() {
return $this->belongsTo('App\Meal')->where('meal_category_id',1);
}
public function soup2() {
return $this->belongsTo('App\Meal')->where('meal_category_id',1);
}
public function mealy() {
return $this->belongsTo('App\Meal')->where('meal_category_id',7);
}
public function scopeSoups($query)
{
return $query->where('meal_category_id', 1);
}
public function scopeMealy($query)
{
return $query->where('meal_category_id', 7);
}
I want to receive filtered list of options instead of all model rows.
You can do this easily by overriding the blades in voyager:
Copy relationship.blade.php
from: /"YourProject"/vendor/tcg/voyager/resources/views/formfields/relationship.blade.php
To: /"YourProject"/resources/views/vendor/voyager/formfields/relationship.blade.php
This way voyager will use this file in your your project views instead of the package file in the vendor.
Read More: Voyager Documentations
In the line 25 of relationship.blade.php
you'll see this block of code:
<select
class="form-control select2-ajax" name="{{ $options->column }}"
data-get-items-route="{{route('voyager.' . $dataType->slug.'.relation')}}"
data-get-items-field="{{$row->field}}"
>
@php
$model = app($options->model);
$query = $model::where($options->key, $dataTypeContent->{$options->column})->get();
@endphp
@if(!$row->required)
<option value="">{{__('voyager::generic.none')}}</option>
@endif
@foreach($query as $relationshipData)
<option value="{{ $relationshipData->{$options->key} }}" @if($dataTypeContent->{$options->column} == $relationshipData->{$options->key}){{ 'selected="selected"' }}@endif>{{ $relationshipData->{$options->label} }}</option>
@endforeach
</select>
Which you should override it with this:
@if($options->table == 'categories')
<div class="ap-form-input">
@php
$model = app($options->model);
$query = $model::where('active', true)->get();
@endphp
<select class="form-control select2" id="language-select" name="{{ $options->column }}">
@if(!$row->required)
<option value="">{{__('voyager::generic.none')}}</option>
@endif
@foreach($query as $relationshipData)
<option value={{ $relationshipData->{$options->key} }} @if($dataTypeContent->{$options->column} == $relationshipData->{$options->key}){{ 'selected="selected"' }}@endif>{{ $relationshipData->{$options->label} }}</option>
@endforeach
</select>
</div>
@else
<div class="ap-form-input">
<select class="form-control select2" name="{{ $options->column }}">
@php
$model = app($options->model);
$query = $model::all();
@endphp
@if(!$row->required)
<option value="">{{__('voyager::generic.none')}}</option>
@endif
@foreach($query as $relationshipData)
<option value={{ $relationshipData->{$options->key} }} @if($dataTypeContent->{$options->column} == $relationshipData->{$options->key}){{ 'selected="selected"' }}@endif>{{ $relationshipData->{$options->label} }}</option>
@endforeach
</select>
</div>
@endif
This way when you're using categories relationship you will only get the active categories.