将hasManyThrough应用于更深层次的关系

时间:2016-12-25 01:14:44

标签: php laravel eloquent relationship

Laravel文档似乎表明hasManyThrough声明只能用于两个级别的关系" deep"。更复杂的关系怎么样?例如,User有许多Subject个,其中每个都有Deck个,其中每个Card都有Deck个。使用User声明获取属于hasManyThrough的所有Card很简单,但属于User的所有pip install C:\path\to\numpy‑1.11.3+mkl‑cp36‑cp36m‑win_amd64.whl 又如何呢? ?

3 个答案:

答案 0 :(得分:1)

正如评论中所述,hasManyThrough并不支持这种特异性水平。您可以做的一件事是返回一个反方向的查询构建器实例:

//App\User;

public function cards()
{
    Card::whereHas('decks', function($q){
         return $q->whereHas('subjects', function($q){
            return $q->where('user_id', $this->id);
        });
    });
}

我们来自Cards -> Decks -> Subjectssubjects应该有user_id列,然后我们可以将其锁定。

从用户模型调用时,会发生这种情况:

$user->cards()->get();

答案 1 :(得分:0)

嗯,实际上最好的解决方案是将额外的列添加到Card表 - user_id,如果您经常需要为用户获取所有卡片。

Laravel为2深度关系提供了Has-Many-Through关系,因为这是非常广泛使用的关系。 对于Laravel不支持的关系,你需要自己找出最佳的表关系。

无论如何,出于您的目的,您可以使用以下代码捕捉来为当前关系模型抓取用户的所有卡片。

  

假设

  • 用户与Deck有hasManyThough的关系,

所以Project模型将包含以下代码:

 public function decks()
    {
        return $this->hasManyThrough('Deck', 'Subject');
    }
  • Deck与Card
  • hasMany的关系
  

代码

$deck_with_cards = $user->decks()->with("cards")->get();
$cards = [];
foreach($deck_with_cards AS $deck) {
  foreach ($deck->cards as $c) {
    $cards[] = $c->toArray();
  }
}

现在$cards拥有$user的所有卡片。

答案 2 :(得分:0)

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

安装后,您可以像这样使用它:

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

    public function cards() {
        return $this->hasManyDeep(Card::class, [Subject::class, Deck::class]);
    }
}