【问题标题】:Laravel relationship between three tables三张表之间的laravel关系
【发布时间】: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 只会包含该年龄的几本书,而不是与该年龄相关的所有书籍。

标签: php laravel orm eloquent model


【解决方案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 显示的内容。
猜你喜欢
  • 2019-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多