Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
php:laravel:relations [2024/10/10 01:32] – создано mirocowphp:laravel:relations [2024/10/10 02:37] (текущий) mirocow
Строка 1: Строка 1:
-====== Relations ======+{{tag>laravel framework php}}
  
 +{{backlinks>.}}
 +
 +====== Отношения / Relations ======
 +
 +  * Отношения «один к одному»
 +  * Отношение «один ко многим»
 +  * Имеет отношение «один из многих»
 +  * Отношения HasOneThrough и HasManyThrough
 +  * Отношение «многие ко многим»
 +  * Полиморфные отношения
 +  * Полиморфный Один к одному
 +  * Полиморфный Один Ко Многим
 +  * Полиморфный Один из Многих
 +  * Полиморфный Многие-К-Многим
 +
 +===== Ссылки =====
 +
 +  * [[https://habr.com/ru/articles/494658/|Используем трейты для полиморфных связей]]
 +
 +===== Отношения «один к одному» =====
 +
 +{{:php:laravel:one-to-one.png?600|}}
 +
 +<code bash>
 +$ php artisan make:model Tenant 
 +$ Php artisan make:model Rent
 +</code>
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Tenant extends Model
 +{
 +    /**
 +    * Get the rent of a Tenant
 +    */
 +    public function rent() 
 +    {
 +        return $this->hasOne(Rent::class);
 +        //return $this- >hasOne(Rent::class, "custom_key");
 +        //return $this->hasOne(Rent::class, "custom_key", "other_key"); 
 +    } 
 +}
 +
 +$rent = Tenant::find(10)->rent;
 +</code>
 +
 +===== Отношение «один ко многим» =====
 +
 +{{:php:laravel:one-to-many.png?600|}}
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Tenant extends Model
 +{
 +    /**
 +    * Get the rents of a Tenant
 +    */
 +    public function rent() 
 +    {
 +        return $this->hasMany(Rent::class);
 +        //return $this->hasMany(Rent::class, "foreign_key");
 +        //return $this->hasMany(Rent::class, "foreign_key", "local_key");
 +    }
 +}
 +
 +$rents = Tenant::find(10)->rent()->where('payment', '>', 500)->first();
 +</code>
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Rent extends Model
 +{
 +    /**
 +    * Return the tenant for the rent
 +    */
 +    public function tenant() 
 +    {
 +        return $this->belongsTo(Tenant::class);
 +    }
 +}
 +
 +$tenant = Rent::find(1)->tenant;
 +</code>
 +
 +===== Имеет отношение «один из многих» =====
 +
 +
 +<code php>
 +public function latestRent() {
 +    return $this->hasOne(Rent::class)->latestOfMany();
 +}
 +
 +public function oldestRent() {
 +    return $this->hasOne(Rent::class)->oldestOfMany();
 +}
 +
 +return $this->hasOne(Rent::class)->ofMany('price', 'min');
 +</code>
 +
 +===== Отношения HasOneThrough и HasManyThrough =====
 +
 +{{:php:laravel:has-one-through.png?600|}}
 +
 +<code>
 +rent
 +    id - integer
 +    name - string
 +    value - double
 +
 +tenants
 +    id - integer
 +    name - string
 +    rent_id - integer
 +
 +landlord
 +    id - integer
 +    name - string
 +    tenant_id - integer
 +</code>
 +    
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Rent extends Model
 +{
 +    /**
 +    * Return the rents' landlord
 +    */
 +    public function rentLandlord() 
 +    {
 +        return $this->hasOneThrough(Landlord::class, Tenant::class);
 +    }
 +}
 +</code>
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Tenant extends Model
 +{
 +    /**
 +    * Get the rents of a Tenant
 +    */
 +    public function rent() 
 +    {
 +        return $this->hasMany(Rent::class);
 +    }
 +}
 +</code>
 +
 +<code php>
 +
 +</code>
 +
 +===== Аналогично, отношение «Has Many Through» =====
 +
 +{{:php:laravel:has-many-through.png?600|}}
 +
 +<code>
 +country
 +    id - integer
 +    name - string
 +
 +user
 +    id - integer
 +    country_id - integer
 +    name - string
 +
 +games
 +    id - integer
 +    user_id - integer
 +    title - string
 +
 +</code>
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Country extends Model
 +{
 +    protected $fillable = ['name'];
 +
 +    public function users()
 +    {
 +        return $this->hasMany(User::class);
 +    }
 +
 +    public function games()
 +    {
 +        return $this->hasManyThrough(Games::class, User::class);
 +    }
 +}
 +</code>
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class User extends Model
 +{
 +    protected $fillable = [article_id, 'name'];
 +
 +    public function country()
 +    {
 +        return $this->belongsTo(Country::class);
 +    }
 +
 +    public function posts()
 +    {
 +        return $this->hasMany(Post::class);
 +    }
 +}
 +</code>
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Game extends Model
 +{
 +    protected $fillable = ['user_id', 'title'];
 +
 +    public function user()
 +    {
 +        return $this->belongsTo(User::class);
 +    }
 +}
 +</code>
 +
 +<code php>
 +<?php
 +
 +$country = Country::find(159);
 +            
 +// Retrieve all games for the country
 +$games = $country->games;
 +</code>
 +
 +===== Отношение «многие ко многим» =====
 +
 +{{:php:laravel:many-to-many.png?600|}}
 +
 +<code>
 +employees
 +    id - integer
 +    name - string
 +
 +roles 
 +    id - integer
 +    name - string
 +
 +role_employees
 +    user_id - integer
 +    role_id - integer
 +</code>
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Employee extends Model
 +{
 +    public function roles() 
 +    {
 +        return $this- >belongsToMany(Role::class);
 +    }
 +}
 +</code>
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Role extends Model
 +{
 +    public function employees() 
 +    {
 +        return $this->belongsToMany(Employee::class);
 +        return $this->belongsToMany(Employee::class)
 +            ->withPivot("active", "created_at");
 +        return $this->belongsToMany(Employee::class)
 +            ->withTimestamps();
 +        return $this->belongsToMany(Employee::class)
 +            ->as('subscription')
 +            ->withPivot("active", "created_by");
 +        return $this->belongsToMany(Employee::class)
 +            ->wherePivot('promoted', 1);
 +        return $this->belongsToMany(Employee::class)
 +            ->wherePivotIn('level', [1, 2]);
 +        return $this->belongsToMany(Employee::class)
 +            ->wherePivotNotIn('level', [2, 3]);
 +        return $this->belongsToMany(Employee::class)
 +            ->wherePivotBetween('posted_at', ['2023-01-01 00:00:00', '2023-01-02 00:00:00']);
 +        return $this->belongsToMany(Employee::class)
 +            ->wherePivotNull('expired_at');
 +        return $this->belongsToMany(Employee::class)
 +            ->wherePivotNotNull('posted_at');
 +          return $this->belongsToMany(Employee::class)
 +            ->where('promoted', true)
 +            ->orderByPivot('hired_at', 'desc');
 +        return $this->belongsToMany(Employee::class)
 +                            ->using(RoleEmployees::class)
 +                            ->withPivot([
 +                                'user_id',
 +                                'role_id'
 +                            ]);
 +    }
 +}
 +</code>
 +
 +<code php>
 +class RoleEmployees 
 +{
 +
 +}
 +</code>
 +
 +<code php>
 +$employee = Employee::find(1);
 +$employee->roles->forEach(function($role) { // });
 +$employee = Employee::find(1)->roles()->orderBy('name')->where('name', 'admin')->get();
 +</code>
 +
 +===== Полиморфный Один к одному =====
 +
 +{{:php:laravel:one-to-one-polymorphic.png?600|}}
 +
 +<code>
 +tenants
 +    id – integer
 +    name – string
 +
 +landlords
 +    id – integer
 +    name – string
 +
 +waterbills
 +    id – integer
 +    amount – double
 +    waterbillable_id
 +    waterbillable_type
 +</code>
 +    
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class WaterBill extends Model
 +{
 +    public function billable()
 +    {
 +        return $this->morphTo();
 +    }
 +}
 +
 +class Tenant extends Model
 +{
 +    public function waterBill()    
 +    {
 +        return $this->morphOne(WaterBill::class, 'billable');
 +    }
 +}
 +
 +class Landlord extends Model
 +{
 +    public function waterBill()    
 +    {
 +        return $this->morphOne(WaterBill::class, 'billable');
 +    }
 +}
 +</code>
 +
 +<code php>
 +<?php
 +
 +$tenant = Tenant::find(1)->waterBill;
 +$landlord = Landlord::find(1)->waterBill;
 +</code>
 +
 +===== Полиморфный Один Ко Многим =====
 +
 +{{:php:laravel:one-to-many-polymorphic.png?600|}}
 +
 +<code>
 +posts 
 +    id – integer
 +    title – string
 +    body – text
 +
 +videos
 +    id – integer
 +    title – string
 +    url – string
 +
 +polls
 +    id – integer
 +    title – string
 +
 +comments 
 +    id – integer
 +    body – text
 +    commentable_id – integer
 +    commentable_type – string
 +</code>
 +    
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Comment extends Model 
 +{
 +    public function commentable()
 +    {
 +        return $this->morphTo();
 +    }
 +}
 +
 +class Poll extends Model
 +{
 +    public function comments()
 +    {
 +        return $this->morphMany(Comment::class, 'commentable');
 +    }
 +}
 +
 +class Live extends Model
 +{
 +    public function comments()
 +    {
 +        return $this->morphMany(Comments::class, 'commentable');
 +    }
 +}
 +</code>
 +
 +<code php>
 +<?php
 +
 +use App\Models\Live;
 +use App\Models\Comment;
 +
 +$live = Live::find(1);
 +
 +foreach ($live->comments as $comment) { }
 +
 +// OR
 +
 +Live::find(1)->comments()->each(function($comment) { // });
 +Live::find(1)->comments()->map(function($comment) { // });
 +Live::find(1)->comments()->filter(function($comment) { // });
 +
 +$comment = Comment::find(10);
 +$commentable = $comment->commentable;
 +</code>
 +
 +===== Полиморфный Один из Многих =====
 +
 +
 +
 +===== Полиморфный Многие-К-Многим =====
 +
 +{{:php:laravel:many-to-many-polymorphic.png?600|}}
 +
 +<code>
 +videos
 +    id – integer
 +    description – string
 +
 +stories 
 +    id – integer
 +    description – string
 +
 +taggables 
 +    tag_id – integer
 +    taggable_id – integer
 +    taggable_type – string
 +</code>
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Video extends Model
 +{
 +    public function tags()
 +    {
 +        return $this->morphToMany(Tag::class, 'taggable');
 +    }
 +}
 +</code>
 +
 +<code php>
 +<?php
 +
 +namespace App\Models;
 +use Illuminate\Database\Eloquent\Model;
 +
 +class Tag extends Model
 +{
 +    public function stories()
 +    {
 +        return $this->morphedByMany(Story::class, 'taggable');
 +    }
 +
 +    public function videos()
 +    {
 +        return $this->morphedByMany(Video::class, 'taggable');
 +    } 
 +}
 +</code>
 +
 +<code php>
 +<?php
 +use App\Model\Tag;
 +
 +$tag = Tag::find(10);
 +$posts = $tag->stories;
 +$videos = $tag->stories;
 +</code>