【问题标题】:Querying Distant Relationships查询远方关系
【发布时间】:2019-03-31 20:41:47
【问题描述】:

我有三个表:usersaccountshotels. 用户和帐户通过 belongstoMany 关系连接,并且帐户和酒店的连接方式相同。每个用户都有帐户,这些帐户有酒店。

当我有Auth::user(), 时,我如何返回所有酒店?

$accounts = Auth::user()->accounts()->get();

通过上面的语句,我可以得到所有的Accounts。如何退回所有酒店?

我尝试了什么?

public function index(Request $request)
    {
        $accounts = Auth::user()->accounts()->get();
        $hotels = collect();
        foreach ($accounts as $key => $a) {

            $h = $a->hotels();
            $hotels = $hotels->toBase()->merge($h);

                }
            dd($hotels);
        return view('hotels.index',compact('hotels'));

    }

但是这段代码不会返回我可以在刀片视图文件中使用的酒店集合

【问题讨论】:

    标签: laravel foreach eloquent


    【解决方案1】:

    案例一

    如果你的关系如下图所示

    您正在寻找的是hasManyThrough 关系。

    来自Laravel documentation

    “has-many-through”关系为通过中间关系访问远距离关系提供了便捷的捷径

    在您的情况下,在您的用户模型上,您可以定义关系

    public function hotels()
    {
      return $this->hasManyThrough('App\Hotel', 'App\Account');
    }
    

    然后,您可以简单地使用您的酒店集合

    $hotels = Auth::user()->hotels;
    

    您还可以为 hasManyThrough 函数提供额外的参数来定义每个表上使用的键,上面链接的文档中给出了很好的示例!

    案例 2

    如果相反,您的关系如下图所示

    它有点棘手(或者,至少,不太干净)。我能想到的使用最少查询的最佳解决方案是使用with

    $accounts = Auth::user()->accounts()->with('hotels')->get();
    

    将为您提供一组帐户,每个帐户都有一个hotels 子级。现在,我们要做的就是将酒店作为一个独立的集合,这很简单,Laravel 提供了一些简洁的集合功能。

    $hotels = $accounts->flatMap(function($account) {
      return $account->hotels;
    })->unique(function ($hotel) {
      return $hotel->id;
    });
    

    这将完成创建酒店集合的工作。在我看来,如下所示,简单地建立一个新的关系会更简洁、更有效

    然后使用基本的 Eloquent 方法执行查询。

    【讨论】:

    • 我试过但我得到了错误:“”SQLSTATE[42S22]:找不到列:1054 '字段列表'中的未知列'Accounts.user_id'(SQL:选择Hotels.*,@ 987654337@.user_id from Hotels 内连接▶""
    • 用户和账户存储在account_user表中,酒店和账户连接存储在hotel_account表中......
    • 所以 hasManyThrough 在我的情况下不起作用,我在获得帐户后需要进行 foreach 循环并查找酒店,然后按 ID 查找该组?对吗?
    • @AleksPer ,是的,我明白了。我误解了人际关系。我将不得不考虑为您的设置执行此操作并发布更新的最佳方法。一般来说,您希望最大限度地减少查询数量,因此您当然不希望在 for 循环中进行查询,因为这可能会对您的响应时间产生巨大影响!
    • 是的,我不想要 foreach 循环,而且用户和账户之间的关系也是多对多的,账户和酒店之间也是如此。谢谢你帮助我
    猜你喜欢
    • 2019-06-13
    • 1970-01-01
    • 2020-11-08
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多