三张表之间的laravel关系

Posted

技术标签:

【中文标题】三张表之间的laravel关系【英文标题】:Laravel relationship between three tables 【发布时间】:2019-04-26 17:56:09 【问题描述】:

我有 3 张桌子:

活动 年龄 书籍

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

年龄

身份证 姓名

书籍

身份证 标题

年龄书

身份证 age_id book_id

事件

身份证 姓名

event_age

身份证 event_id age_id

event_age_book

event_age_id book_id

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

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

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 模型上做到这一点?

【问题讨论】:

我无法弄清楚为什么您有最后一张桌子 event_age_book 似乎是多余的,并且容易使您的生活变得不必要地复杂。或许您可以解释一下为什么需要最后一张桌子? @J.A.Streich 我需要 event_age_book,因为 event_age 只会包含该年龄的几本书,而不是与该年龄相关的所有书籍。 【参考方案1】:

让我们回顾一下关系

看来你应该只需要 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

【讨论】:

我需要age_event_book,因为age_event 将只有少数选定的书籍,而不是与该年龄相关的所有书籍。感谢您的回复。 那一定是一个age_event 有....(意味着另一个模型和更多的关系)还是它比一个事件有很多书。 一个有很多书的事件并不重要,只是有很多书的事件年龄和有很多年龄的事件,因为在前端我需要获取最新的事件和组书按年龄划分,书籍可以属于多个年龄。 我认为不可能,因为对于活动年龄,我只想选择该年龄的几本书,并且所选书籍也可以在同一活动中为另一个年龄选择。 已编辑。这是一个粗略的草图。它可以进行更多优化,但它可以为您提供 imgur 显示的内容。

以上是关于三张表之间的laravel关系的主要内容,如果未能解决你的问题,请参考以下文章

如何在 laravel eloquent 中查询三张表

Laravel 中多对多关系中连接表的命名约定

Laravel5.1 模型 --多对多关系

Laravel 定义同一张表的多对多关系

Laravel:同一张表,一对一的关系

与同一张表的关系(多对多?) - Laravel