【问题标题】:Stuck on eloquent relationships - pivot and polymorphic relationship坚持雄辩的关系 - 枢轴和多态关系
【发布时间】:2016-03-12 22:46:53
【问题描述】:

您好,我一直在尝试获取属于某个用户的所有 cmets,其中枢轴位于这两个模型之间。我似乎无法理解它,否则我的数据库架构可能是完全错误的。无论如何,我希望得到一些帮助。

目前我的模型如下所示:

User.php

class User extends Model 
{
    // Grab all the beers that this user has checked in to his personal profile
    public function beers()
    {
        return $this->belongsToMany('App\Beer')->withTimestamps()->withPivot('rating', 'description');
    }
}

Beer.php(枢轴关系)

class Beer extends Model
{
    // polymorphic relationship grab all comments that belong to this beer
    public function comments()
    {
        return $this->morphMany('App\Comment', 'commentable');
    }
}

Comment.php(设置为多态)

class Comment extends Model
{
    public function commentable()
    {
        return $this->morphTo();
    }

    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

此处的代码抓取属于啤酒数据透视记录的所有 cmets。这很好用,因为 $user->beers 考虑到我们正在处理特定的用户配置文件,并且只从特定的 $user 中找到数据透视记录。

$user = User::find($id);

@foreach($user->beers as $beer)
    @foreach($beer->comments as $comment)
    {{ $comment }}
    @endforeach
@endforeach

不幸的是,cmets 关系只查看 cmets 表中的 commentable_id 和 commentable_type,并没有考虑当前的 user_id(我们当前正在查看的配置文件),所以当我查看具有相同 beer_user 的用户的另一个配置文件时在他的个人资料中,同样的 cmets 也会出现在其中。

如何调用 Beer.php 模型的 cmets 关系,以便同时考虑 user_id?显然我已经在我的 cmets 表中添加了一个 user_id。我以前也试过问这个问题,但我希望这次更详细一点,现在人们可以帮助我,我也知道如何最终更好地表述这个问题。

数据库:

【问题讨论】:

  • 您是否尝试链接您的查询,例如 $beer->cmets()->where('user_id', '=', $user->id) ?顺便问一下,你打算有用户评论吗?如果您只是愿意为 Beers by Users 提供评论,则不需要 morph 关系。
  • 我不明白。你想实现什么查询?
  • 抓取属于特定用户的所有啤酒,然后抓取放置在该用户啤酒上的所有 cmets。当我从我的示例中执行查询时,它可以工作,但查询不考虑数据透视记录 beer_id/user_id 组合。

标签: laravel eloquent schema laravel-5.2 relationships


【解决方案1】:

在这个特定的代码示例中,我将只使用带有用户 ID 约束的即时加载:

$user = User::with(['beers', 'beers.comments' => function ($query) use ($id) {
    $query->whereHas('user', function ($query) use ($id) {
        $query->where('id', $id);
    });
}])->find($id);

@foreach($user->beers as $beer)
    @foreach($beer->comments as $comment)
    {{ $comment }}
    @endforeach
@endforeach

这种急切加载约束仅在您提前获得用户 ID 时才有效。

但是,想象一下,您无法限制急切加载或查询以获取 cmets。事后您仍然可以过滤 cmets 集合:

@foreach($user->beers as $beer)
    @foreach($beer->comments->where('user_id', $user->id) as $comment)
    {{ $comment }}
    @endforeach
@endforeach

【讨论】:

  • 非常感谢,我已经在研究如何在 foreach 循环中添加 where 子句了。我尝试做一些愚蠢的事情,比如将参数传递给关系,但最后它就像添加 where 子句一样简单。当然,我会坚持使用急切的加载,但非常感谢你,非常感谢你的帮助。被困在这个问题上的时间比我想承认的要长,哈哈。
  • 经过进一步测试,我意识到这仍然不是我想要的。您提供的查询会检查评论表中的 user_id,但我需要检查 beer_user 数据透视表中的 user_id。评论表中的 user_id 只是告诉了哪个用户发表了这条评论。我需要能够对我的数据透视表的某个 beer_id、user_id 组合进行评论,并且当我输入 App\Beer 作为commentable_type 时只需搜索 beer_id。不过感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2021-01-16
  • 2017-10-16
  • 2014-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-23
相关资源
最近更新 更多