【问题标题】:Laravel : querying sub relationships via modelsLaravel:通过模型查询子关系
【发布时间】:2020-07-01 12:24:23
【问题描述】:

鉴于我有一个专辑、类别、作者和角色模型:

  • 相册有一个类别和多个作者
  • 一个作者有很多类别和很多专辑
  • 对于给定的专辑,作者有多个角色(pivot "album_id")

以下是关系:

// Album.php
class Album extends Model
{
  public function category()
  {
    return $this->morphedByMany(Category::class, 'albumable');
  }

  public function authors()
  {
    return $this->morphedByMany(Author::class, 'albumable');
  }
}
// Category.php
class Category extends Model
{
  public function albums()
  {
    return $this->morphToMany(Album::class, 'albumable');
  }

  public function authors()
  {
    return $this->belongsToMany(Author::class);
  }
}
// Author.php
class Author extends Model
{
  public function albums()
  {
    return $this->morphToMany(Album::class, 'albumable');
  }

  public function categories()
  {
    return $this->belongsToMany(Category::class);
  }

  public function roles()
  {
    return $this->belongsToMany(Role::class)->withPivot('album_id');
  }  
}
// Role.php
class Role extends Model
{
  public function authors()
  {
    return $this->belongsToMany(Author::class)->withPivot('album_id');
  }
}

对于给定的作者(路由作者/id),我想列出该特定作者的所有专辑以及专辑的角色。该列表必须按类别组织。 例如,类似的东西:

Author (id: 1)
John DOE

Category (id: 1)
  Album (id: 1)
    Roles (id: 1)
    Roles (id: 2)
  Album (id: 2)
      Roles (id: 5)
      Roles (id: 8)
      Roles (id: 12)

Category (id: 2)
  Album (id: 3)
    Roles (id: 1)
  Album (id: 4)
      Roles (id: 5)

...

通过 Eloquent 关系,我设法“有点”我正在寻找的东西......

// AuthorController.php
class AuthorController extends Controller
{
    public function show($id)
    {
        $author = Author::where('id', '=', $id)->with([
          'categories.albums.authors' => function ($query) use ($id) {
              $query->where('id', '=', $id); // Only the current author
          },
          'categories.albums.authors.roles'
        ])
        ->get();

        return $author;
    }
}

但我在作者的角色中挣扎。我无法获得专辑的作者角色。这是为所有专辑检索的所有作者角色。

在我看来,问题是我无法检索关系“categories.albums.authors.roles”中的作者和专辑之间的链接......

非常感谢任何帮助! :)

【问题讨论】:

  • 我猜你想循环作者的所有类别并显示每个类别的书籍以及特定书籍的作者角色,但请听我说。您能否获取特定作者的所有书籍,然后从 Book 模型中获取类别和角色?如果类别不多,您可以在 PHP 上循环并将结果按类别排列到数组中,甚至可以使用集合函数 group() 将它们分组。
  • 感谢您的回复。我也在考虑同样的事情,但缺点是我在刀片模板中有一些逻辑:/。我希望有一种使用 Eloquent 的“更清洁”的方式。
  • 我认为我对急切加载约束很满意,但问题是我不知道如何检索关系 categories.albums.authors.roles 中的 **$album_id **。
  • 那么就有可能有一些应该工作的东西:'categories.albums.authors.roles' => function ($query) use ($id) { $query->where('album_id', '=', $album_id); }

标签: php laravel eloquent


【解决方案1】:

如果你想要分类最好从分类开始:

    $author = Author::find($id);
    $categories_related_to_author = 
    // get categories that has albums that has roloes that has our author.
    Category::whereHas('albums',function($query) use($id) { 
        return $query->whereHas('roles',function($query) use($id) {
               return $query->whereHas('authors',function($query) use($id) {
                    return $query->where('id',$id);
               });
         });
    })
    ->with([  
      'albums.roles.authors' // include albums and roles of their authors
    ])
    ->get();

【讨论】:

  • 谢谢,但很抱歉,我就是这样做的,从类别开始到角色 ('categories.albums.authors.roles')。
  • 顺便说一下,专辑中不存在作者和角色之间的关系
  • 抱歉没注意。我要说的是 with 不会过滤嵌套关系,而 whereHas 会使用嵌套关系进行过滤。
  • 谢谢,显然with() 允许您过滤查询。现在我尝试像最初那样查询 Collection 模型而不是 Author 并且我拥有了我想要的结构(收藏 > 专辑 > 作者 > 角色)。但我仍然坚持专辑的角色:(
  • 'albums.authors.roles' => function ($query) use ($album_id) { $query->where('album_id', '=', $album_id); // How to get $album_id ? }
【解决方案2】:

准确地说,这是我的 author_role

+-----------+---------+----------+
| author_id | role_id | album_id |
+-----------+---------+----------+
| 1         | 8       | 1        |
+-----------+---------+----------+
| 1         | 5       | 1        |
+-----------+---------+----------+
| 2         | 12      | 1        |
+-----------+---------+----------+
| 1         | 2       | 2        |
+-----------+---------+----------+

这就是我想要实现的目标:

// AuthorController.php
class AuthorController extends Controller
{
    public function show($id)
    {
        $author = Author::where('id', '=', $id)->with([
          'categories.albums.authors' => function ($query) use ($id) {
              $query->where('id', '=', $id); // Only the current author
          },
          'categories.albums.authors.roles' => function ($query) use ($album_id) {
              $query->where('album_id', '=', $album_id); // How to get $album_id ?
          }
        ])
        ->get();

        return $author;
    }
}

最后$author 应该在访问/authors/1 时返回类似的东西:

Author (id: 1)
John DOE

Category (id: 1)
  Album (id: 1)
    Roles (id: 8)
    Roles (id: 5)
  Album (id: 2)
      Roles (id: 2)

【讨论】:

    猜你喜欢
    • 2021-07-23
    • 2014-01-18
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2016-05-04
    • 2020-03-16
    • 2015-08-06
    相关资源
    最近更新 更多