- Основы
- Заголовок столбца
- Pivot
- Создание объекта отношения
- Выбор
- Опции
- Placeholder
- Дерево
- Предпросмотр
- Только ссылка
- Запрос для значений
- Асинхронный поиск
- Связанные поля
- Значения с изображением
- Кнопки
Основы
Поле BelongsToMany предназначено для работы с отношением того же имени в Laravel и включает все базовые методы.
Для создания этого поля используйте статический метод make()
.
BelongsToMany::make(Closure|string $label,?string $relationName = null,Closure|string|null $formatted = null,?ModelResource $resource = null)
BelongsToMany::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\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', 'categories', resource: new CategoryResource())];}
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', 'categories', resource: new CategoryResource())];}
Если вы не указываете $relationName
, тогда имя отношения будет определено автоматически на основе $label
.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())];}//...
Вы можете опустить $resource
, если ресурс модели соответствует имени отношения.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', 'categories')];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', 'categories')];}//...
По умолчанию для отображения значения используется поле в связанной таблице, которое указано свойством $column
в ресурсе модели.
Аргумент $formatted
позволяет переопределить это.
namespace App\MoonShine\Resources;use MoonShine\Resources\ModelResource;class CategoryResource extends ModelResource{//...public string $column = 'title';//...}
namespace App\MoonShine\Resources;use MoonShine\Resources\ModelResource;class CategoryResource extends ModelResource{//...public string $column = 'title';//...}
Если вам нужно указать более сложное значение для отображения, тогда в аргумент $formatted
можно передать функцию обратного вызова.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories','categories',fn($item) => "$item->id. $item->title")];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories','categories',fn($item) => "$item->id. $item->title")];}//...
Заголовок столбца
По умолчанию заголовок столбца таблицы использует свойство $title
ресурса модели отношения.
Метод columnLabel()
позволяет переопределить заголовок.
columnLabel(string $label)
columnLabel(string $label)
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->columnLabel('Title')];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->columnLabel('Title')];}//...
Pivot
Метод fields()
используется для реализации полей pivot в отношении BelongsToMany.
fields(Fields|Closure|array $fields)
fields(Fields|Closure|array $fields)
use MoonShine\Fields\Relationships\BelongsToMany;use MoonShine\Fields\Text;//...public function fields(): array{return [BelongsToMany::make('Contacts', resource: new ContactResource())->fields([Text::make('Contact', 'text'),])];}//...
use MoonShine\Fields\Relationships\BelongsToMany;use MoonShine\Fields\Text;//...public function fields(): array{return [BelongsToMany::make('Contacts', resource: new ContactResource())->fields([Text::make('Contact', 'text'),])];}//...
В отношении необходимо указать, какие поля pivot используются в промежуточной таблице! Подробнее в официальной документации Laravel.
Создание объекта отношения
Метод creatable()
позволяет создать новый объект отношения через модальное окно.
creatable(Closure|bool|null $condition = null,?ActionButton $button = null,)
creatable(Closure|bool|null $condition = null,?ActionButton $button = null,)
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->creatable()];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->creatable()];}//...
Вы можете настроить кнопку создания, передав параметр button в метод.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->creatable(button: ActionButton::make('Custom button', ''))];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->creatable(button: ActionButton::make('Custom button', ''))];}//...
Выбор
Поле BelongsToMany может быть отображено в виде выпадающего списка. Для этого необходимо использовать метод selectMode()
.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->selectMode()];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->selectMode()];}//...
Опции
Все опции выбора доступны для изменения через атрибуты data:
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Countries', resource: new CountryResource())->selectMode()->customAttributes(['data-max-item-count' => 2])];}
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Countries', resource: new CountryResource())->selectMode()->customAttributes(['data-max-item-count' => 2])];}
Для получения более подробной информации, пожалуйста, обратитесь к Choices.
Placeholder
Метод placeholder()
позволяет установить атрибут placeholder на поле.
placeholder(string $value)
placeholder(string $value)
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Countries', 'countries')->nullable()->placeholder('Countries')];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Countries', 'countries')->nullable()->placeholder('Countries')];}//...
Метод placeholder()
используется только если поле отображается в виде выпадающего списка selectMode()
!
Дерево
Метод tree()
позволяет отображать значения в виде дерева с чекбоксами, например, для категорий, которые имеют вложенность. В метод необходимо передать столбец в базе данных, по которому будет строиться дерево.
tree(string $parentColumn)
tree(string $parentColumn)
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->tree('parent_id')];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->tree('parent_id')];}//...
Предпросмотр
По умолчанию в preview поле будет отображаться в виде таблицы.
Для изменения отображения в preview можно использовать следующие методы.
onlyCount
Метод onlyCount()
позволяет отображать только количество выбранных значений в preview.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->onlyCount()];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->onlyCount()];}//...
inLine
Метод inLine()
позволяет отображать значения поля в виде строки.
inLine(string $separator = '', Closure|bool $badge = false, ?Closure $link = null)
inLine(string $separator = '', Closure|bool $badge = false, ?Closure $link = null)
Вы можете передать в метод необязательные параметры:
separator
- разделитель между элементами;badge
- замыкание или булево значение, отвечающее за отображение элементов в виде бейджа;$link
- замыкание, которое должно возвращать ссылки url или компоненты.
При передаче булевого значения true в параметр badge
будет использоваться цвет Primary. Для изменения цвета отображаемого badge
используйте замыкание и возвращайте компонент Badge::make()
.
use MoonShine\Components\Link;use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->inLine(separator: ' ',badge: fn($model, $value) => Badge::make($value, 'color'),link: fn(Category $category, $value, $field) => Link::make((new CategoryResource())->detailPageUrl($category),$value))];}//...
use MoonShine\Components\Link;use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->inLine(separator: ' ',badge: fn($model, $value) => Badge::make($value, 'color'),link: fn(Category $category, $value, $field) => Link::make((new CategoryResource())->detailPageUrl($category),$value))];}//...
Только ссылка
Метод onlyLink()
позволит отобразить отношение в виде ссылки с количеством элементов.
onlyLink(?string $linkRelation = null, Closure|bool $condition = null)
onlyLink(?string $linkRelation = null, Closure|bool $condition = null)
Вы можете передать в метод необязательные параметры:
linkRelation
- ссылка на отношение;condition
- замыкание или булево значение, отвечающее за отображение отношения в виде ссылки.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->onlyLink('category')];}
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->onlyLink('category')];}
linkRelation
Параметр linkRelation
позволяет создать ссылку на отношение с привязкой родительского ресурса.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->onlyLink('category')];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->onlyLink('category')];}//...
condition
Параметр condition
через замыкание позволит изменить метод отображения в зависимости от условий.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->onlyLink(condition: function (int $count, Field $field): bool {return $count > 10;})];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->onlyLink(condition: function (int $count, Field $field): bool {return $count > 10;})];}//...
Запрос для значений
Метод valuesQuery()
позволяет изменить запрос для получения значений.
valuesQuery(Closure $callback)
valuesQuery(Closure $callback)
use Illuminate\Contracts\Database\Eloquent\Builder;use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Countries', 'countries', resource: new CountryResource())->valuesQuery(fn(Builder $query, Field $field) => $query->where('active', true))];}
use Illuminate\Contracts\Database\Eloquent\Builder;use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Countries', 'countries', resource: new CountryResource())->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,)
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\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Countries', 'countries', resource: new CountryResource())->asyncSearch()];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Countries', 'countries', resource: new CountryResource())->asyncSearch()];}//...
Поиск будет осуществляться по полю отношения ресурса column
. По умолчанию column=id
Вы можете передать параметры в метод asyncSearch()
:
$asyncSearchColumn
- поле, по которому осуществляется поиск,$asyncSearchCount
- количество элементов в результатах поиска,$asyncSearchQuery
- функция обратного вызова для фильтрации значений,$asyncSearchValueCallback
- функция обратного вызова для настройки вывода,$associatedWith
- поле, с которым устанавливается связь,$url
- url для обработки асинхронного запроса,$replaceQuery
- заменить запрос.
use Illuminate\Contracts\Database\Eloquent\Builder;use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Countries', 'countries', 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;},'/async')];}//...
use Illuminate\Contracts\Database\Eloquent\Builder;use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Countries', 'countries', 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;},'/async')];}//...
При построении запроса в asyncSearchQuery()
вы можете использовать текущие значения формы. Для этого нужно передать Request
в функцию обратного вызова.
use Illuminate\Contracts\Database\Eloquent\Builder;use Illuminate\Http\Request;use MoonShine\Fields\Relationships\BelongsToMany;use MoonShine\Fields\Select;//...public function fields(): array{return [Select::make('Country', 'country_id'),BelongsToMany::make('Cities', 'cities', resource: new CityResource())->asyncSearch('title',asyncSearchQuery: function (Builder $query, Request $request, Field $field): Builder {return $query->where('country_id', $request->get('country_id'));})];}//...
use Illuminate\Contracts\Database\Eloquent\Builder;use Illuminate\Http\Request;use MoonShine\Fields\Relationships\BelongsToMany;use MoonShine\Fields\Select;//...public function fields(): array{return [Select::make('Country', 'country_id'),BelongsToMany::make('Cities', 'cities', resource: new CityResource())->asyncSearch('title',asyncSearchQuery: function (Builder $query, Request $request, Field $field): Builder {return $query->where('country_id', $request->get('country_id'));})];}//...
При построении запроса в asyncSearchQuery()
сохраняется исходное состояние построителя запросов.
Если вам нужно заменить его своим построителем, тогда используйте флаг replaceQuery
.
use Illuminate\Contracts\Database\Eloquent\Builder;use Illuminate\Http\Request;use MoonShine\Fields\Relationships\BelongsToMany;use MoonShine\Fields\Select;//...public function fields(): array{return [Select::make('Country', 'country_id'),BelongsToMany::make('Cities', 'cities', 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)];}//...
use Illuminate\Contracts\Database\Eloquent\Builder;use Illuminate\Http\Request;use MoonShine\Fields\Relationships\BelongsToMany;use MoonShine\Fields\Select;//...public function fields(): array{return [Select::make('Country', 'country_id'),BelongsToMany::make('Cities', 'cities', 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)];}//...
Запросы должны быть настроены с использованием метода asyncSearch()
. Не используйте valuesQuery()
!
Связанные поля
Для установления связи значений выбора между полями можно использовать метод associatedWith()
.
associatedWith(string $column, ?Closure $asyncSearchQuery = null)
associatedWith(string $column, ?Closure $asyncSearchQuery = null)
$column
- поле, с которым устанавливается связь,$asyncSearchQuery
- функция обратного вызова для фильтрации значений.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Cities', 'cities', resource: new CityResource())->associatedWith('country_id')];}
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Cities', 'cities', resource: new CityResource())->associatedWith('country_id')];}
[TIP] Для более сложной настройки вы можете использовать
asyncSearch()
.
Значения с изображением
Метод withImage()
позволяет добавить изображение к значению.
withImage(string $column,string $disk = 'public',string $dir = '')
withImage(string $column,string $disk = 'public',string $dir = '')
$column
- поле с изображением,$disk
- диск файловой системы,$dir
- директория относительно корня диска.
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make(Countries, resource: new CountryResource())->withImage('thumb', 'public', 'countries')->selectMode()];}//...
use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make(Countries, resource: new CountryResource())->withImage('thumb', 'public', 'countries')->selectMode()];}//...
Кнопки
Метод buttons()
позволяет добавить дополнительные кнопки к полю BelongsToMany.
buttons(array $buttons)
buttons(array $buttons)
use MoonShine\ActionButtons\ActionButton;use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->buttons([ActionButton::make('Check all', '')->onClick(fn() => 'checkAll', 'prevent'),ActionButton::make('Uncheck all', '')->onClick(fn() => 'uncheckAll', 'prevent')])];}
use MoonShine\ActionButtons\ActionButton;use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->buttons([ActionButton::make('Check all', '')->onClick(fn() => 'checkAll', 'prevent'),ActionButton::make('Uncheck all', '')->onClick(fn() => 'uncheckAll', 'prevent')])];}
withCheckAll
Метод withCheckAll()
позволяет добавить кнопки checkAll/uncheckAll к полю BelongsToMany, аналогично предыдущему примеру.
use MoonShine\ActionButtons\ActionButton;use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->withCheckAll()];}//...
use MoonShine\ActionButtons\ActionButton;use MoonShine\Fields\Relationships\BelongsToMany;//...public function fields(): array{return [BelongsToMany::make('Categories', resource: new CategoryResource())->withCheckAll()];}//...