BelongsTo

# Basics

The BelongsTo field is designed to work with the relation of the same name in Laravel and includes all the basic methods.

To create this field, use the static make() method.

BelongsTo::make(
Closure|string $label,
?string $relationName = null,
Closure|string|null $formatted = null,
?ModelResource $resource = null
)
  • $label - label, field header,
  • $relationName - name of the relationship,
  • $formatted - a closure or field in a related table to display values,
  • $resource - the model resource referenced by the relation.

The presence of the model resource referenced by the relation is mandatory!
The resource also needs to be registered with the service provider MoonShineServiceProvider in the method menu() or resources(). Otherwise, there will be a 404 error.

use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('Country', 'country', resource: new CountryResource())
];
}
 
//...

If you do not specify $relationName, then the relation name will be determined automatically based on $label.

use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('Country', resource: new CountryResource())
];
}
 
//...

You can omit $resource if the model resource matches the name of the relationship.

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

By default, a field in the related table is used to display the value. which is specified by the $column property in the model resource.
The $formatted argument allows you to override this.

namespace App\MoonShine\Resources;
 
use MoonShine\Resources\ModelResource;
 
class CountryResource extends ModelResource
{
//...
 
public string $column = 'title';
 
//...
}

If you need to specify a more complex value to display, then the $formatted argument can be passed a callback function.

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

When using the BelongsTo field to sort or filter positions, you must use the method setColumn() set a field in a database table or override a method sorting at the model resource.

If you need to change column when working with models, use the onAfterFill method

BelongsTo::make(
'Category',
resource: new CategoryResource()
)->afterFill(fn($field) => $field->setColumn('changed_category_id'))

# Default value

You can use the default() method if you need to specify a default value for a field.

default(mixed $default)

You must pass a model object as the default value.

use App\Models\Country;
use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('Country', resource: new CountryResource())
->default(Country::find(1))
];
}
 
//...

# Nullable

Like all fields, if you need to store NULL, you need to add the nullable() method

nullable(Closure|bool|null $condition = null)
use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('Country', resource: new CountryResource())
->nullable()
];
}
 
//...

Don't forget to indicate in the database table that the field can take the value Null.

# Placeholder

The placeholder() method allows you to set placeholder attribute on the field.

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

# Finding values

If you need to search among values, 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()
];
}
 
//...

# Creating a Relationship Object

The creatable() method allows you to create a new relation object through a modal window.

creatable(
Closure|bool|null $condition = null,
?ActionButton $button = null,
)
use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('Author', resource: new AuthorResource())
->creatable()
];
}
 
//...

You can customize the create button by passing the button parameter to the method.

use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('Author', resource: new AuthorResource())
->creatable(
button: ActionButton::make('Custom button', '')
)
];
}
 
//...

# Query for values

The valuesQuery() method allows you to change the query for obtaining values.

valuesQuery(Closure $callback)
use Illuminate\Contracts\Database\Eloquent\Builder;
use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('Category', 'category', resource: new CategoryResource())
->valuesQuery(fn(Builder $query, Field $field) => $query->where('active', true))
];
}
 
//...

To implement asynchronous search for values, use the asyncSearch() method.

asyncSearch(
string $asyncSearchColumn = null,
int $asyncSearchCount = 15,
?Closure $asyncSearchQuery = null,
?Closure $asyncSearchValueCallback = null,
?string $associatedWith = null,
?string $url = null,
bool $replaceQuery = false,
)
use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('Country', 'country', resource: new CountryResource())
->asyncSearch()
];
}
 
//...

The search will be carried out using the resource relationship field column. By default column=id.

You can pass parameters to the asyncSearch() method:

  • $asyncSearchColumn - the field in which the search takes place;
  • $asyncSearchCount - number of elements in the search results;
  • $asyncSearchQuery - callback-function for filtering values;
  • $asyncSearchValueCallback - callback-function for customizing output;
  • $associatedWith - the field with which to establish a connection;
  • $url - url to process the asynchronous request,
  • $replaceQuery - replace query.
use Illuminate\Contracts\Database\Eloquent\Builder;
use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('Country', 'country', resource: new CountryResource())
->asyncSearch(
'title',
10,
asyncSearchQuery: function (Builder $query, Request $request, Field $field) {
return $query->where('id', '!=', 2);
},
asyncSearchValueCallback: function ($country, Field $field) {
return $country->id . ' | ' . $country->title;
},
'https://moonshine-laravel.com/async'
)
];
}
 
//...

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

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

When building a query in asyncSearchQuery(), the original state of the builder is preserved.
If you need to replace it with your builder, then use the replaceQuery flag.

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

# Related fields

To associate select values between fields, you can use the associatedWith() method.

associatedWith(string $column, ?Closure $asyncSearchQuery = null)
  • $column - the field with which the connection is established;
  • $asyncSearchQuery - callback function for filtering values.
use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('City', 'city', resource: new CityResource())
->associatedWith('country_id')
];
}
 
//...

For more complex setup, you can use asyncSearch().

# Values with picture

The withImage() method allows you to add an image to a value.

withImage(
string $column,
string $disk = 'public',
string $dir = ''
)
  • $column - field with an image;
  • $disk - file system disk;
  • $dir - directory relative to the root of the disk.
use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make(Country, resource: new CountryResource())
->withImage('thumb', 'public', 'countries')
];
}
 
//...

# Options

All choices options are available to change via data attributes:

use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('Country', resource: new CountryResource())
->searchable()
->customAttributes([
'data-search-result-limit' => 5
])
];
}
 
//...

For more details please contact Choices .

# Native mode

The native() method disables the Choices.js library and displays select in native mode

BelongsTo::make('Type')->native()