Поиск…
Запрос на отношения
Eloquent также позволяет вам запрашивать определенные отношения, как показано ниже:
User::whereHas('articles', function (Builder $query) {
$query->where('published', '!=', true);
})->get();
Это требует, чтобы в этом случае ваше имя метода взаимодействия - это articles
. Аргумент, переданный в закрытие, представляет собой Query Builder для связанной модели, поэтому вы можете использовать любые запросы, которые вы можете найти в другом месте.
Веселая загрузка
Предположим, что модель пользователя имеет отношение к модели Article, и вы хотите, чтобы она загружала связанные статьи. Это означает, что статьи пользователя будут загружаться при извлечении пользователя.
articles
- это имя отношения (метод) в модели пользователя.
User::with('articles')->get();
если у вас много отношений. например, статей и сообщений.
User::with('articles','posts')->get();
и выбрать вложенные отношения
User::with('posts.comments')->get();
Вызов более чем одной вложенной связи
User::with('posts.comments.likes')->get()
Вставка похожих моделей
Предположим, у вас есть модель Post
с отношениями hasMany
с Comment
. Вы можете вставить объект Comment
связанный с сообщением, выполнив следующие действия:
$post = Post::find(1);
$commentToAdd = new Comment(['message' => 'This is a comment.']);
$post->comments()->save($commentToAdd);
Вы можете сохранить сразу несколько моделей с помощью функции saveMany
:
$post = Post::find(1);
$post->comments()->saveMany([
new Comment(['message' => 'This a new comment']),
new Comment(['message' => 'Me too!']),
new Comment(['message' => 'Eloquent is awesome!'])
]);
Кроме того, существует также метод create
который принимает простой PHP-массив вместо экземпляра модели Eloquent.
$post = Post::find(1);
$post->comments()->create([
'message' => 'This is a new comment message'
]);
Вступление
Яркие отношения определяются как функции в классах модели Eloquent. Поскольку, как и сами модели Eloquent, отношения также служат мощными строителями запросов, определяя отношения как функции, обеспечивая мощные возможности цепочки и запросов. Например, мы можем связать дополнительные ограничения в отношении этих сообщений:
$user->posts()->where('active', 1)->get();
Типы отношений
Один ко многим
Допустим, что каждый пост может иметь один или несколько комментариев, и каждый комментарий принадлежит только одному сообщению.
поэтому в таблице комментариев будет post_id
. В этом случае отношения будут следующими.
Почтовая модель
public function comments()
{
return $this->belongsTo(Post::class);
}
Если внешний ключ отличается от post_id
, например, внешний ключ - example_post_id
.
public function comments()
{
return $this->belongsTo(Post::class, 'example_post_id');
}
и плюс, если локальный ключ отличается от id
, например, локальным ключом является other_id
public function comments()
{
return $this->belongsTo(Post::class, 'example_post_id', 'other_id');
}
Модель комментария
определение обратного от одного к многим
public function post()
{
return $this->hasMany(Comment::class);
}
Один к одному
Как установить связь между двумя моделями (пример: модель User
и Phone
)
App\User
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get the phone record associated with the user.
*/
public function phone()
{
return $this->hasOne('Phone::class', 'foreign_key', 'local_key');
}
}
App\Phone
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model
{
/**
* Get the user that owns the phone.
*/
public function user()
{
return $this->belongsTo('User::class', 'foreign_key', 'local_key');
}
}
foreign_key
: По умолчанию Eloquent примет это значение как other_model_name_id
(в этом случае user_id
и phone_id
), измените его, если это не так.
local_key
: По умолчанию Eloquent будет считать это значение id
(текущий первичный ключ модели), измените его, если это не так.
Если ваша база данных указала имя по стандарту laravel, вам не нужно предоставлять внешний ключ и локальный ключ в объявлении отношений
объяснение
Многим многим
Допустим, есть роли и разрешения. Каждая роль может принадлежать многим разрешениям, и каждое разрешение может принадлежать ко многим ролям. поэтому будет 3 таблицы. две модели и одна сводная таблица. roles
, users
и таблица permission_role
.
Ролевая модель
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
Модель разрешения
public function roles()
{
return $this->belongsToMany(Roles::class);
}
Примечание: 1
рассмотрите следующее, используя другое имя таблицы для сводной таблицы.
Предположим, если вы хотите использовать role_permission
вместо permission_role
, поскольку красноречивый использует буквенный порядок для создания имен ключевых ключей. вам нужно будет передать имя сводной таблицы в качестве второго параметра следующим образом.
Ролевая модель
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission');
}
Модель разрешения
public function roles()
{
return $this->belongsToMany(Roles::class, 'role_permission');
}
Заметка 2
рассмотрите следующие при использовании разных имен ключей в сводной таблице.
Красноречивый предполагает, что если никакие ключи не передаются третьим и четвертым параметрами, это будут уникальные имена таблиц с _id
. поэтому он предполагает, что в pivot будут поля role_id
и permission_id
. Если ключи, отличные от них, должны использоваться, они должны быть переданы как третий, так и четвертый параметры.
Допустим , если other_role_id
вместо role_id
и other_permission_id
вместо permission_id
будет использоваться. Так было бы так.
Ролевая модель
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission', 'other_role_id', 'other_permission_id');
}
Модель разрешения
public function roles()
{
return $this->belongsToMany(Roles::class, 'role_permission', 'other_permission_id', 'other_role_id');
}
полиморфный
Полиморфные отношения позволяют модели относиться к более чем одной другой модели в одной ассоциации. Хорошим примером могут быть изображения, как пользователь, так и продукт могут иметь изображение. Структура таблицы может выглядеть следующим образом:
user
id - integer
name - string
email - string
product
id - integer
title - string
SKU - string
image
id - integer
url - string
imageable_id - integer
imageable_type - string
Важные столбцы для просмотра находятся в таблице изображений. imageable_id
будет содержать значение идентификатора пользователя или продукта, в то время imageable_type
столбец imageable_type
будет содержать имя класса модели владельца. В ваших моделях вы устанавливаете отношения следующим образом:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
/**
* Get all of the owning imageable models.
*/
public function imageable()
{
return $this->morphTo();
}
}
class User extends Model
{
/**
* Get all of the user's images.
*/
public function images()
{
return $this->morphMany('Image::class', 'imageable');
}
}
class Product extends Model
{
/**
* Get all of the product's images.
*/
public function images()
{
return $this->morphMany('Image::class', 'imageable');
}
}
Вы также можете получить владельца полиморфного отношения из полиморфной модели, обратившись к имени метода, который выполняет вызов morphTo
. В нашем случае это imageable
метод на модели изображения. Таким образом, мы получим доступ к этому методу как динамическое свойство
$image = App\Image::find(1);
$imageable = $image->imageable;
Этот imageable
будет возвращать либо Пользователь, либо Продукт.
Много для многих
Допустим, есть роли и разрешения. Каждая роль может принадлежать многим разрешениям, и каждое разрешение может принадлежать ко многим ролям. поэтому будет 3 таблицы. две модели и одна сводная таблица. roles
, users
и таблица permission_role
.
Ролевая модель
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
Модель разрешения
public function roles()
{
return $this->belongsToMany(Roles::class);
}
Примечание: 1
рассмотрите следующее, используя другое имя таблицы для сводной таблицы.
Предположим, если вы хотите использовать role_permission
вместо permission_role
, поскольку красноречивый использует буквенный порядок для создания имен ключевых ключей. вам нужно будет передать имя сводной таблицы в качестве второго параметра следующим образом.
Ролевая модель
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission');
}
Модель разрешения
public function roles()
{
return $this->belongsToMany(Roles::class, 'role_permission');
}
Заметка 2
рассмотрите следующие при использовании разных имен ключей в сводной таблице.
Красноречивый предполагает, что если никакие ключи не передаются третьим и четвертым параметрами, это будут уникальные имена таблиц с _id
. поэтому он предполагает, что в pivot будут поля role_id
и permission_id
. Если ключи, отличные от них, должны использоваться, они должны быть переданы как третий, так и четвертый параметры.
Допустим , если other_role_id
вместо role_id
и other_permission_id
вместо permission_id
будет использоваться. Так было бы так.
Ролевая модель
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission', 'other_role_id', 'other_permission_id');
}
Модель разрешения
public function roles()
{
return $this->belongsToMany(Roles::class, 'role_permission', 'other_permission_id', 'other_role_id');
}
Доступ к промежуточной таблице с помощью команды pivot ()
Предположим, у вас есть третий столбец « permission_assigned_date » в сводной таблице. По умолчанию на сводный объект будут присутствовать только ключи модели. Теперь, чтобы получить этот столбец в результате запроса, вам нужно добавить имя в функцию withPivot ().
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission', 'other_role_id', 'other_permission_id')->withPivot('permission_assigned_date');
}
Прикрепление / отсоединение
Eloquent также предоставляет несколько дополнительных вспомогательных методов, чтобы сделать работу с родственными моделями более удобной. Например, давайте представим, что у пользователя может быть много ролей, а роль может иметь много разрешений. Чтобы прикрепить роль к разрешению, вставив запись в промежуточную таблицу, которая присоединяется к моделям, используйте метод attach:
$role= App\Role::find(1);
$role->permissions()->attach($permissionId);
При присоединении отношения к модели вы также можете передать массив дополнительных данных, которые необходимо вставить в промежуточную таблицу:
$rol->roles()->attach($permissionId, ['permission_assigned_date' => $date]);
Аналогично, Чтобы удалить конкретное разрешение на роль, используйте функцию отладки
$role= App\Role::find(1);
//will remove permission 1,2,3 against role 1
$role->permissions()->detach([1, 2, 3]);
Синхронизация ассоциаций
Вы также можете использовать метод sync для построения ассоциаций «многие-ко-многим». Метод синхронизации принимает массив идентификаторов для размещения на промежуточной таблице. Любые идентификаторы, которые не находятся в данном массиве, будут удалены из промежуточной таблицы. Таким образом, после завершения этой операции в промежуточной таблице будут существовать только идентификаторы в данном массиве:
//will keep permission id's 1,2,3 against Role id 1
$role= App\Role::find(1)
$role->permissions()->sync([1, 2, 3]);