BelongsTo

You're browsing the documentation for an old version of MoonShine. Consider upgrading your project to MoonShine 2.x.

Extends Select * has the same features

# Basics

Field for relationships in Laravel, BelongsTo type. Displayed as select.

use MoonShine\Fields\BelongsTo;
 
//...
public function fields(): array
{
return [
// indicating the relationship
BelongsTo::make('Country', 'country', 'name')
// or you can field
BelongsTo::make('Country', 'country_id', 'name')
];
}
//...

The third argument with the "name" value is a field in the linked "countries" table to display the values.

You can also pass a resource with a field to display as a third parameter

use MoonShine\Fields\BelongsTo;
use App\MoonShine\Resources\CountryResource;
 
//...
public function fields(): array
{
return [
BelongsTo::make('Country', 'country', new CountryResource())
];
}
//...
namespace App\MoonShine\Resources;
 
use MoonShine\Resources\Resource;
use App\Models\Country;
 
class CountryResource extends Resource
{
//...
 
public string $titleField = 'name';
 
//...
}

If you need a more complex value to display, you can pass a function to the third argument

use MoonShine\Fields\BelongsTo;
 
//...
public function fields(): array
{
return [
BelongsTo::make(
'Country',
'country',
fn($item) => "$item->id.) $item->name"
)
];
}
//...

# Searching values

If you need to search among values, then you need to add the searchable() method.

use MoonShine\Fields\BelongsTo;
use App\MoonShine\Resources\CountryResource;
 
//...
public function fields(): array
{
return [
BelongsTo::make('Country', 'country', new CountryResource())
->searchable()
];
}
//...

Async search for values is provided by the asyncSearch() method.

use MoonShine\Fields\BelongsTo;
 
//...
public function fields(): array
{
return [
BelongsTo::make('Contacts')
->asyncSearch()
];
}
//...

The search will be performed on the resource relation field titleField. The default is titleField=id.

You can pass parameters to the asyncSearch() method:

  • title - search field
  • count - amount of items in output
  • asyncSearchQuery() - callback function for filtering values
  • asyncSearchValueCallback() - callback function for output customization.

use Illuminate\Contracts\Database\Eloquent\Builder;
use MoonShine\Fields\BelongsTo;
 
//...
public function fields(): array
{
return [
BelongsTo::make('Contacts')->asyncSearch(
'title',
10,
asyncSearchQuery: function (Builder $query) {
return $query->where('id', '!=', 2);
},
asyncSearchValueCallback: function ($contact) {
return $contact->id . ' | ' . $contact->title;
}
)
];
}
//...

When building a query in asyncSearchQuery(), you can use the current form values. To do this, you need to pass Request to the callback functions.

use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use MoonShine\Fields\BelongsTo;
use MoonShine\Fields\Select;
 
//...
public function fields(): array
{
return [
Select::make('Country', 'country_id'),
BelongsTo::make('City')->asyncSearch(
'title',
asyncSearchQuery: function (Builder $query, Request $request): Builder {
return $query->where('country_id', $request->get('country_id'));
}
)
];
}
//...

Relations that use async search in their fields are recommended to be used in ResourceMode.

# Values query

To filter values, use the valuesQuery method
use Illuminate\Contracts\Database\Eloquent\Builder;
use MoonShine\Fields\BelongsTo;
 
//...
public function fields(): array
{
return [
BelongsTo::make('Categories', 'categories', 'name')
->valuesQuery(fn(Builder $query) => $query->where('active', true))
];
}
//...

# Empty value

If you need the default value Null

use MoonShine\Fields\BelongsTo;
 
//...
public function fields(): array
{
return [
BelongsTo::make('Country', 'country')
->nullable()
];
}
//...

Don't forget to specify in the database table that the field can be Null.