BelongsTo

# Основы

Поле BelongsTo предназначено для работы с одноименным отношением в Laravel и включает в себя все базовые методы.

Для создания данного поля используется статический метод make().

BelongsTo::make(
Closure|string $label,
?string $relationName = null,
Closure|string|null $formatted = null,
?ModelResource $resource = null
)
  • $label - лейбл, заголовок поля,
  • $relationName - название отношения,
  • $formatted - замыкание или поле в связанной таблице для отображения значений,
  • $resource - ресурс модели на которую ссылается отношение.

Наличие ресурса модели, на которую ссылается отношение, обязательно!
Ресурс также необходимо зарегистрировать в сервис провайдере MoonShineServiceProvider в методе menu() или resources(). Иначе, будет 404 ошибка.

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

Если не указать $relationName, то название отношения будет определено автоматически на основе $label.

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

Можно не указывать $resource, если ресурс модели соответствует названию отношения.

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

По умолчанию для отображения значения используется поле в связанной таблице, которое задано свойством $column в ресурсе модели.
Аргумент $formatted позволяет это переопределить.

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

Если необходимо задать более сложное значение для отображения, то аргументу $formatted можно передать callback функцию.

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

При использовании поля BelongsTo для сортировки или фильтрации позиций необходимо через метод setColumn() задать поле в таблице базы данных или переопределить метод сортировки у ресурса модели.

Если при работе с моделями необходимо изменить column, то воспользуйтесь методом onAfterFill

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

# Значение по умолчанию

Можно воспользоваться методом default(), если необходимо указать значение по умолчанию для поля.

default(mixed $default)

В качестве значения по умолчанию необходимо передать объект модели.

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

Как и у всех полей, если необходимо сохранять NULL, то нужно добавить метод nullable()

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

Не забудьте в таблице базы данных указать, что поле может принимать значение Null.

# Placeholder

Метод placeholder() позволяет задать у поля атрибут placeholder.

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

# Поиск значений

Если необходим поиск среди значений, то нужно добавить метод searchable().

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

# Создание объекта отношения

Метод creatable() позволяет создавать новый объект отношения через модальное окно.

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()
];
}
 
//...

Кастомизировать кнопку создания можно передав методу параметр button.

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

# Запрос для значений

Методом valuesQuery() позволяет изменить запрос на получение значений.

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))
];
}
 
//...

Для реализации асинхронного поиска значений воспользуйтесь методом asyncSearch().

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()
];
}
 
//...

Поиск будет осуществляться по полю отношения ресурса column. По умолчанию column=id.

В метод asyncSearch() можно передавать параметры:

  • $asyncSearchColumn - поле по которому происходит поиск;
  • $asyncSearchCount - количество элементов в выдаче;
  • $asyncSearchQuery - callback-функция для фильтрации значений;
  • $asyncSearchValueCallback - callback-функция для кастомизации вывода;
  • $associatedWith - поле с которым необходимо установить связь;
  • $url - url для обработки асинхронного запроса,
  • $replaceQuery - заменить запрос.
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'
)
];
}
 
//...

При построении запроса в asyncSearchQuery() можно использовать текущие значения формы. Для этого необходимо передать Request в callback-функции.

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'));
}
)
];
}
 
//...

При построении запроса в asyncSearchQuery() исходное состояние builder сохраняется.
Если вам требуется заменить на свой builder, то воспользуйтесь флагом replaceQuery.

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
)
];
}
 
//...

# Связанные поля

Для связывания значений селектов между полями можно воспользоваться методом associatedWith().

associatedWith(string $column, ?Closure $asyncSearchQuery = null)
  • $column - поле с которым устанавливается связь;
  • $asyncSearchQuery - callback-функция для фильтрации значений.
use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make('City', 'city', resource: new CityResource())
->associatedWith('country_id')
];
}
 
//...

Для более сложной настройки можно использовать asyncSearch().

# Значения с изображением

Метод withImage() позволяет добавить изображение к значению.

withImage(
string $column,
string $disk = 'public',
string $dir = ''
)
  • $column - поле с изображением;
  • $disk - диск файловой системы;
  • $dir - директория относительно корня диска.
use MoonShine\Fields\Relationships\BelongsTo;
 
//...
 
public function fields(): array
{
return [
BelongsTo::make(Country, resource: new CountryResource())
->withImage('thumb', 'public', 'countries')
];
}
 
//...

# Опции

Все опции choices доступны для изменения через 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
])
];
}
 
//...

За более подробной информацией обратитесь к Choices .

# Нативный режим

Метод native() отключает библиотеку Choices.js и выводит select в нативном режиме

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