【问题标题】:Laravel, getting deep relationshipsLaravel,建立深厚的关系
【发布时间】:2018-09-23 07:33:53
【问题描述】:

我有以下结构:

'buildings' 有很多'blocks' 里面有很多'units' 里面有很多 '租户'

我需要获取居住在建筑物中的所有租户的列表。

Laravel 提供了 hasMany 和 hasManyThrough 命令,可帮助您获取具有直接关系或通过单个中间表相关的模型集合,但如果您想获取两层、三层或任何深度的相关元素怎么办?

使用 Laravel/Eloquent 实现此目的的正确方法是什么?

【问题讨论】:

  • 使用whereHas
  • 或者只是使用一系列JOINs。但是你尝试了什么?
  • 尝试阅读 Laravel 文档,然后在没有任何尝试提示的情况下随机接触。
  • @devk, whereHas 只会让你获得两层深度,在这个例子中将获得建筑物的单位。我认为没有办法链接 whereHas 语句。
  • @fubar,我尝试过的是ugly,我不希望回复基于此。我想知道实现这一目标的正确 laravel/雄辩方式是什么

标签: laravel eloquent


【解决方案1】:

这种情况下没有原生关系。

我创建了一个无限级别的HasManyThrough 关系:Repository on GitHub

安装后可以这样使用:

class Building extends Model {
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function tenants() {
        return $this->hasManyDeep(Tenant::class, [Block::class, Unit::class]);
    }
}

【讨论】:

  • 嘿乔纳斯,非常感谢你,这似乎正是我想要的。我最终将用于构建的外键放入租户表中,这是我试图避免的。我会尝试您的解决方案并回复您。
【解决方案2】:

要查找给定建筑物中的所有租户,最简单的方法是使用JOIN 子句。

我假设你所有的关系都是 hasMany 与 belongsTo 反转的。

$tenants = Tenant::select('tenants.*')
    ->join('units', 'units.id', '=', 'tenant.unit_id')
    ->join('blocks', 'blocks.id', '=', 'units.block_id')
    ->join('buildings', 'buildings.id', '=', 'blocks.building_id')
    ->where('buildings.id', 123)
    ->get();

如果这是您将多次使用的东西,那么我建议在您的 Tenant 模型上创建一个查询范围。

class Tenant extends Eloquent
{
    // ...

    public function scopeInBuilding($query, $buildingId)
    {
        return $query->select('tenants.*')
            ->join('units', 'units.id', '=', 'tenant.unit_id')
            ->join('blocks', 'blocks.id', '=', 'units.block_id')
            ->join('buildings', 'buildings.id', '=', 'blocks.building_id')
            ->where('buildings.id', $buildingId);
    }

    // ...
}

你可以按如下方式使用它:

$tenants = Tenant::inBuilding(123)->get();

【讨论】:

    【解决方案3】:

    我认为您想要做的是嵌套急切加载。就像访问关系与关系:

    例如 如果您的帖子有 cmets 并且 cmets 有回复和 你想要所有带有 cmets 的帖子和 cmets 的回复:

    $posts = Post::with('comment.reply')->get();
    

    链接:https://laravel.com/docs/5.3/eloquent-relationships#eager-loading

    【讨论】:

      【解决方案4】:

      有几种计算方法。

      1. 首先,您可以定义建筑物和街区之间的多重关系。
      2. 为使用单元的建筑物的每个街区查找租户,街区和租户之间存在许多直通关系。

      【讨论】:

      • 这是我目前正在做的事情,但随着关系的深入,它变得非常丑陋
      【解决方案5】:

      首先在各个模型中定义关系(一对一/一对多) 然后可以使用 with helper 检索该关系数据 例如;

      $users = User::with('podcasts')->get();
      // here podcasts is the defined relationship in user model
      

      【讨论】:

      • 嘿 HCK,感谢您的回复,但这只会让我更深一层,我需要访问其表之间没有直接关系的数据。
      • @paishin 大声笑我刚刚编辑了这个问题。答案来自 kshitij。希望你解决了。
      猜你喜欢
      • 2019-08-18
      • 2021-12-17
      • 1970-01-01
      • 2018-02-15
      • 2022-01-24
      • 2021-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多