Fields

BelongsTo

Basics

The BelongsTo field is designed to work with the same-name relationship in Laravel and includes all Basic Methods.

BelongsTo::make(
Closure|string $label,
?string $relationName = null,
Closure|string|null $formatted = null,
ModelResource|string|null $resource = null,
)
BelongsTo::make(
Closure|string $label,
?string $relationName = null,
Closure|string|null $formatted = null,
ModelResource|string|null $resource = null,
)
  • $label - the label, the title of the field,
  • $relationName - the name of the relation,
  • $formatted - a closure or field in the related table for displaying values,
  • $resource - the ModelResource that the relationship refers to.

Having a ModelResource that the relationship refers to is mandatory. The resource must also be registered in the MoonShineServiceProvider service provider in the $core->resources() method. Otherwise, there will be a 500 error.

 namespaces
use App\MoonShine\Resources\UserResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make(
'User',
'user',
resource: UserResource::class
)
 namespaces
use App\MoonShine\Resources\UserResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make(
'User',
'user',
resource: UserResource::class
)

belongs_to belongs_to_dark

You can omit $resource if the ModelResource matches the relationship name.

use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('User', 'user')
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('User', 'user')

If you do not specify $relationName, the name of the relationship will be determined automatically based on $label (by camelCase rules).

use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('User')
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('User')

By default, the field used to display the value is the one specified by the $column property in the ModelResource. The $formatted argument allows overriding the $column property.

use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make(
'User',
'user',
formatted: 'first_name'
)
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make(
'User',
'user',
formatted: 'first_name'
)

If you need to specify a more complex value for display, you can pass a callback function to the $formatted argument.

use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make(
'Country',
'country',
fn($item) => "$item->id. $item->title"
)
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make(
'Country',
'country',
fn($item) => "$item->id. $item->title"
)

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

 namespaces
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make(
'Category',
resource: CategoryResource::class
)
->afterFill(
fn($field) => $field->setColumn('changed_category_id')
)
 namespaces
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make(
'Category',
resource: CategoryResource::class
)
->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 the field.

default(mixed $default)
default(mixed $default)

You must pass a model object as the default value.

 namespaces
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', resource: CategoryResource::class)
->default(Country::find(1))
 namespaces
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', resource: CategoryResource::class)
->default(Country::find(1))

Nullable

As with all fields, if you need to store NULL, you should add the nullable() method.

nullable(Closure|bool|null $condition = null)
nullable(Closure|bool|null $condition = null)
 namespaces
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', resource: CategoryResource::class)
->nullable()
 namespaces
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', resource: CategoryResource::class)
->nullable()

select_nullable select_nullable_dark

Don't forget to specify in the database table that the field can accept a Null value.

Placeholder

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

placeholder(string $value)
placeholder(string $value)
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', 'country')
->nullable()
->placeholder('Country')
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', 'country')
->nullable()
->placeholder('Country')

Searching Values

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

 namespaces
use App\MoonShine\Resources\CountryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', 'country', resource: CountryResource::class)
->searchable()
 namespaces
use App\MoonShine\Resources\CountryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', 'country', resource: CountryResource::class)
->searchable()

Creating Relation Object

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

creatable(
Closure|bool|null $condition = null,
?ActionButton $button = null,
)
creatable(
Closure|bool|null $condition = null,
?ActionButton $button = null,
)
BelongsTo::make('Author', resource: AuthorResource::class)
->creatable()
BelongsTo::make('Author', resource: AuthorResource::class)
->creatable()

belongs_to_creatable belongs_to_creatable_dark

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

 namespaces
use App\MoonShine\Resources\AuthorResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
use MoonShine\UI\Components\ActionButton;
 
BelongsTo::make('Author', resource: AuthorResource::class)
->creatable(
button: ActionButton::make('Custom button', '')
)
 namespaces
use App\MoonShine\Resources\AuthorResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
use MoonShine\UI\Components\ActionButton;
 
BelongsTo::make('Author', resource: AuthorResource::class)
->creatable(
button: ActionButton::make('Custom button', '')
)

Query for Values

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

valuesQuery(Closure $callback)
valuesQuery(Closure $callback)
 namespaces
use App\MoonShine\Resources\CategoryResource;
use Illuminate\Contracts\Database\Eloquent\Builder;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
use MoonShine\UI\Fields\Field;
 
BelongsTo::make('Category', 'category', resource: CategoryResource::class)
->valuesQuery(fn(Builder $query, Field $field) => $query->where('active', true))
 namespaces
use App\MoonShine\Resources\CategoryResource;
use Illuminate\Contracts\Database\Eloquent\Builder;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
use MoonShine\UI\Fields\Field;
 
BelongsTo::make('Category', 'category', resource: CategoryResource::class)
->valuesQuery(fn(Builder $query, Field $field) => $query->where('active', true))

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

asyncSearch(
string $column = null,
?Closure $searchQuery = null,
?Closure $formatted = null,
?string $associatedWith = null,
int $limit = 15,
?string $url = null,
)
asyncSearch(
string $column = null,
?Closure $searchQuery = null,
?Closure $formatted = null,
?string $associatedWith = null,
int $limit = 15,
?string $url = null,
)
 namespaces
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Category', 'category', resource: CategoryResource::class)
->asyncSearch()
 namespaces
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Category', 'category', resource: CategoryResource::class)
->asyncSearch()

The search will be carried out by the field specified for the resource column. By default, column=id.

You can pass parameters to the asyncSearch() method:

  • $column - the field by which the search is conducted,
  • $searchQuery - a callback function for filtering values,
  • $formatted - a callback function for customizing output,
  • $associatedWith - the field with which the association is established,
  • $limit - the number of items in the search results,
  • $url - the URL for processing the asynchronous request.
 namespaces
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use MoonShine\UI\Fields\Field;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Category', 'category', resource: CategoryResource::class)
->asyncSearch(
'title',
searchQuery: function (Builder $query, Request $request, Field $field) {
return $query->where('id', '!=', 2);
},
formatted: function ($country, Field $field) {
return $country->id . ' | ' . $country->title;
},
limit: 10,
url: 'https://moonshine-laravel.com/async'
)
 namespaces
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use MoonShine\UI\Fields\Field;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Category', 'category', resource: CategoryResource::class)
->asyncSearch(
'title',
searchQuery: function (Builder $query, Request $request, Field $field) {
return $query->where('id', '!=', 2);
},
formatted: function ($country, Field $field) {
return $country->id . ' | ' . $country->title;
},
limit: 10,
url: 'https://moonshine-laravel.com/async'
)

When building the query in searchQuery, you can use the current values of the form. To do this, it is necessary to pass Request into the callback function.

 namespaces
use App\MoonShine\Resources\CityResource;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
use MoonShine\UI\Fields\Field;
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id'),
 
BelongsTo::make('City', 'city', resource: CityResource::class)
->asyncSearch(
'title',
searchQuery: function (Builder $query, Request $request, Field $field): Builder {
return $query->where('country_id', $request->get('country_id'));
}
)
 namespaces
use App\MoonShine\Resources\CityResource;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
use MoonShine\UI\Fields\Field;
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id'),
 
BelongsTo::make('City', 'city', resource: CityResource::class)
->asyncSearch(
'title',
searchQuery: function (Builder $query, Request $request, Field $field): Builder {
return $query->where('country_id', $request->get('country_id'));
}
)

When building the query in searchQuery, the initial state of the builder is preserved. If you need to replace it with your builder, use the replaceQuery flag.

 namespaces
use App\MoonShine\Resources\CityResource;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
use MoonShine\UI\Fields\Field;
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id'),
 
BelongsTo::make('City', 'city', resource: CityResource::class)
->asyncSearch(
'title',
searchQuery: function (Builder $query, Request $request, Field $field): Builder {
return $query->where('country_id', $request->get('country_id'));
},
replaceQuery: true
)
 namespaces
use App\MoonShine\Resources\CityResource;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
use MoonShine\UI\Fields\Field;
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id'),
 
BelongsTo::make('City', 'city', resource: CityResource::class)
->asyncSearch(
'title',
searchQuery: function (Builder $query, Request $request, Field $field): Builder {
return $query->where('country_id', $request->get('country_id'));
},
replaceQuery: true
)

Associated Fields

To establish a relationship of selection values between fields, you can use the associatedWith() method.

associatedWith(string $column, ?Closure $searchQuery = null)
associatedWith(string $column, ?Closure $searchQuery = null)
  • $column - the field with which the relationship is established,
  • $searchQuery - a callback function for filtering values.
 namespaces
use App\MoonShine\Resources\CityResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('City', 'city', resource: CityResource::class)
->associatedWith('country_id')
 namespaces
use App\MoonShine\Resources\CityResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('City', 'city', resource: CityResource::class)
->associatedWith('country_id')

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

Values with Image

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

withImage(
string $column,
string $disk = 'public',
string $dir = ''
)
withImage(
string $column,
string $disk = 'public',
string $dir = ''
)
  • $column - the field with the image,
  • $disk - the file system disk,
  • $dir - the directory relative to the root of the disk.
 namespaces
use App\MoonShine\Resources\CountryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', resource: CountryResource::class)
->withImage('thumb', 'public', 'countries')
 namespaces
use App\MoonShine\Resources\CountryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', resource: CountryResource::class)
->withImage('thumb', 'public', 'countries')

belongs_to_image belongs_to_image_dark

Options

All selection options are available for modification via data attributes:

 namespaces
use App\MoonShine\Resources\CountryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', resource: CountryResource::class)
->searchable()
->customAttributes([
'data-search-result-limit' => 5
])
 namespaces
use App\MoonShine\Resources\CountryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Country', resource: CountryResource::class)
->searchable()
->customAttributes([
'data-search-result-limit' => 5
])

For more detailed information, please refer to Choices.

Native Mode

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

use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Type')->native()
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make('Type')->native()

By default, BelongsTo links to the edit page. You can override this behavior using the link() method.

 namespaces
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make(
'Category',
'category',
resource: CategoryResource::class,
)
->link(
link: fn(string $value, BelongsTo $ctx) => $ctx->getResource()->getDetailPageUrl($ctx->getData()->getKey()),
name: fn(string $value) => $value,
icon: 'users',
blank: true,
)
 namespaces
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Laravel\Fields\Relationships\BelongsTo;
 
BelongsTo::make(
'Category',
'category',
resource: CategoryResource::class,
)
->link(
link: fn(string $value, BelongsTo $ctx) => $ctx->getResource()->getDetailPageUrl($ctx->getData()->getKey()),
name: fn(string $value) => $value,
icon: 'users',
blank: true,
)