Связь один к одному
Связь один к одному - это когда одна запись одной таблицы соответствует одной записи другой таблицы.
Давайте посмотрим на примере, пусть у нас есть следующая таблица с постами:
posts
id
title
Каждый пост имеет одну картинку-миниатюру, при этом картинки хранятся в отдельной таблице:
thumbnails
id
path
alt
post_id
Таблица с миниатюрами связана с таблицей с постами через поле post_id
. Так как одному посту соответствует одна миниатюра, то у нас получается связь один к одному
. Мы можем прописать эту связь в моделях наших таблиц, тогда при получении поста вместе с ним автоматически будет получаться и миниатюра.
Давайте сделаем это, создадим модель для миниатюр:
app/Models/Thumbnail.php<?php
class Thumbnail extends Model
{
}
Создадим модель для постов:
app/Models/Post.php<?php
class Post extends Model
{
}
Заюзаем в модели для постов модель для миниатюр:
app/Models/Post.php<?php
use App\Models\Thumbnail;
class Post extends Model
{
}
В модели для постов создадим метод thumbnail
:
app/Models/Post.php<?php
class Post extends Model
{
public function thumbnail()
{
}
}
В этом методе свяжем наши модели через метод hasOne
:
app/Models/Post.php<?php
class Post extends Model
{
public function thumbnail()
{
return $this->hasOne(Thumbnail::class);
}
}
Получение данных
Давайте теперь в контроллере получим какой-нибудь пост:
app/Http/Controllers/PostController.php<?php
class PostController extends Controller
{
public function show()
{
$post = Post::find(1);
dump($post);
}
}
Этот пост, будет представлять собой объект в котором свойствами будут поля таблицы. Ввыведем, к примеру содержимое поля title:
app/Http/Controllers/PostController.php<?php
class PostController extends Controller
{
public function show()
{
$post = Post::find(1);
dump($post->title);
}
}
В объекте с постом также появится свойство thumbnail
. Имя этого свойства соответствует методу, который мы сделали в модели с постами для связывания моделей. Это свойство будет содержать объект с миниатюрой:
app/Http/Controllers/PostController.php<?php
class PostController extends Controller
{
public function show()
{
$post = Post::find(1);
dump($post->thumbnail); // объект с миниатюрой
}
}
Давайте выведем какое-нибудь поле нашей миниатюры:
app/Http/Controllers/PostController.php<?php
class PostController extends Controller
{
public function show()
{
$post = Post::find(1);
dump($post->thumbnail->path);
}
}
Перебор записей
Давайте теперь получим не один пост а несколько и перебем их циклом:
app/Http/Controllers/PostController.php<?php
class PostController extends Controller
{
public function show()
{
$posts = Post::all();
foreach ($posts as $post) {
dump($post->title);
}
}
}
При переборе для каждого поста также будет доступно свойство thumbnail
, содержащее миниатюру:
app/Http/Controllers/PostController.php<?php
class PostController extends Controller
{
public function show()
{
$posts = Post::all();
foreach ($posts as $post) {
dump($post->thumbnail);
}
}
}
Давайте выведем какие-нибудь данные нашей миниатюры:
app/Http/Controllers/PostController.php<pre><span></span><code class="highlightjs-php"><?php
class PostController extends Controller
{
public function show()
{
$posts = Post::all();
foreach ($posts as $post) {
dump($post->thumbnail->path);
dump($post->thumbnail->alt);
}
}
}</code></pre>
Обратная связь
Выше у нас была связь один к одному между постом и миниатюрой. Такая связь может трактоваться двояко: каждый пост имеет свою миниатюру или каждая миниатюра принадлежит посту.
Разница проявляется в том, в какой таблице находится поле связи. В нашем случае поле связи - post_id
, находится в таблице с миниатюрами.
Это значит, что пост имеет миниатюру. Но и миниатюра в свою очередь принадлежит посту. На практике это означает, что можно получить миниатюру вместе с ее постом. Для этого нужно связать модель миниатюр с моделью постов через отношение belongsTo
, давайте сделаем это:
app/Models/Thumbnail.php<?php
class Thumbnail extends Model
{
public function post()
{
return $this->belongsTo(Post::class);
}
}
После этого при получении миниатюры можно будет получить ее пост:
app/Http/Controllers/ThumbnailController.php<?php
class ThumbnailController extends Controller
{
public function show()
{
$thumbnail = Thumbnail::find(1);
dump($thumbnail);
dump($thumbnail->post);
}
}
Давайте получим какое-нибудь поле связанного поста:
app/Http/Controllers/ThumbnailController.php<?php
class ThumbnailController extends Controller
{
public function show()
{
$thumbnail = Thumbnail::find(1);
dump($thumbnail->post->title);
}
}