首页 > 解决方案 > 三张表之间的laravel关系

问题描述

我有 3 张桌子:

我通过以下方式将它们联系起来:

基本上,一本书可以有多个时代,一个时代可以有很多书,一个事件可以有很多时代,一个事件时代可以有很多书。

我的事件模型看起来像这样,并且可以很好地获取所有事件年龄

class Event extends Model
{
    public function ages()
    {
        return $this->belongsToMany(Age::class, 'event_age');
    }
}

年龄模型:

class Age extends Model
{
    public function books(): BelongsToMany
    {
        return $this
            ->belongsToMany(Book::class)
            ->withTimestamps();
    }
}

图书模型

class Book extends Model
{
    public function ages(): BelongsToMany
    {
         return $this
            ->belongsToMany(Age::class, 'book_age', 'book_id','age_id')
            ->withTimestamps();
    }
}

我无法弄清楚如何获得所有版本时代的书籍​​,是否可以在 Event 模型上做到这一点?

标签: phplaravelormeloquentmodel

解决方案


让我们回顾一下关系

似乎你应该只需要 3 个模型和 5 个表。

  • 属于时代的书籍
  • 属于时代的事件
  • 时代属于书籍
  • 时代属于事件

您的其他模型没问题,但您的年龄模型缺少与事件的关系:

class Age extends Model
{
    public function books(): BelongsToMany
    {
        return $this->belongsToMany(Book::class)
            ->withTimestamps();
    }

    public function events(): BelongsToMany
    {
        return $this->belongsToMany(Events::class,'event_age')
            ->withTimestamps();
    }
}

这将允许:

$books->ages;
$events->ages;
$ages->book;
$ages->events;

还有链...

$books = collect();
foreach($event->ages as $age){
    $books->merge($ages->books);
}
$books->unique();

书籍和活动

所以,我认为你不想要age_event_books。我认为你真正想要的是:

  • 活动属于书籍
  • 书籍属于活动

这样

book_events
- id
- book_id
- event_id
- age_id

你会在书中:

public function events()
{
    return $this->BelongsToMany('App\Event')
       ->withTimestamps()
       ->withPivot('age_id');
}

在事件中:

public function books()
{
   return $this->belongsToMany('App\Book')->withTimestamps()
      ->withPiviot('age_id')->groupBy('age_id');
}

给你:

$event->books
$book->events

在前端

[O]在前端,我需要按年龄获取最近的事件和分组书籍,书籍可以属于多个年龄

$event = Event::latest();
$books = $event->books();

然后在刀片上

@foreach($books as $age_id => $books)
    <h4>{{Age::find($age_id)->name}}</h4>
    @foreach($books as $book)
       <div>$book->name</div>
    @endforeach
@endforeach

有用的提示

您正在提供关系表,您必须这样做,因为您没有遵循连接表的命名约定。惯例是要加入的类应按字母顺序列出。所以age_event代替event_age.


推荐阅读