Связывание один к одному
Такое связывание помогает объединить записи из разных таблиц, используя ключи. Выглядит примерно как оператор JOIN в SQL с условием полного соответствия значений первичных ключей из разных таблиц.Приведём пример связывания, объединив таблицу с модель с данными пользователей и модель с телефонами. Первая модель имеет столбце id в качестве первичного ключа, а вторая - user_id. Укажем их во втором и третьем параметре метода "hasOne", который делает связывание "один к одному". Первым же параметром он принимает имя связанной модели:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
public function phone() {
return $this->hasOne('App\Phone', 'user_id', 'id');
}
}
?>
По умолчанию Eloquent определяет имя внешнего ключа по имени метода отношения, добавляя суффикс "_id". Поэтому его можно было не задавать в этом примере.
Обратное отношение
В примере выше мы создали доступ из модели User в модель Phone. Теперь сделаем наоборот, используя метод "belongsTo". Аналогично "hasOne" первым параметром задаётся имя связанной модели, вторым и третьим - названия столбцов в дочерней и родительской модели соответственно.<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model {
public function phone() {
return $this->belongsTo('App\User', 'id', 'user_id');
}
}
?>
Один ко многим
Иногда одна модель может соответствовать нескольким. К примеру, отношение пользователя и его комментариев или записей в блоге. Чтобы создать такое отношение, можно использовать метод "hasMany"<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {
public function comments() {
return $this->hasMany('App\Comment');
}
}
?>
Этот пример предполагает, что для модели комментариев существует "post_id". Как было сказано ранее, это название указывается во втором аргументе к функциям связывания. Но если не указывать, то его значение будет браться из названия модели в регистре "snake case" (то есть строчные буквы и разделение слов через подчёркивание "_").
После такого связывания можно обращаться к комментарием статей через свойство:
<?php
$comments = App\Post::find(1)->comments;
foreach ($comments as $comment) {
// выводим комментарии
}
?>
Можно добавлять ещё и условия получения выборки:
<?php
$comments = App\Post::find(1)->comments()->where('id', '>', 42)->first();
foreach ($comments as $comment) {
// выводим комментарии
}
?>
Многие к одному
Доработаем предыдущий пример связи комментариев с публикацией. На этот раз попробуем получить данные публикации из комментария. Использовать можно всё тот же метод "belongsTo", который рассматривали ранее:<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model {
public function post() {
return $this->belongsTo('App\Post');
}
}
?>
Попробуем получить название публикации через комментарий:
<?php
$comment = App\Comment::find(1);
echo $comment->post->title;
?>
Tсли ключ для модели Comment не "post_id", можно передать название вторым параметром в метод "belongsTo". А если в модели Comment не используется "id", то можно указать в качестве первичного ключа значение через третий параметр:
<?php
...
return $this->belongsTo('App\Post', 'ключ_в_Post', 'ключ_в_Comments');
...
?>