如何在 Laravel 中链接数据库关系(多个 has_many?)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15281163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 07:36:23  来源:igfitidea点击:

How to chain DB relationships in Laravel (multiple has_many?)

phpmysqlactiverecordlaraveleloquent

提问by Pete

I'm using Laravel, which is awesome, but I'm stuck on an issue with the database.

我正在使用 Laravel,这很棒,但我遇到了数据库问题。

Let's say we have three tables, like so:

假设我们有三个表,如下所示:

TABLE 1: pages

表 1:页面

id    |   route   |  title

TABLE 2: elements

表 2:元素

id    |   page_id   |  type

TABLE 3: content

表 3:内容

id    |   element_id   |  data

I'd like to do a single selection for the page that will in turn select all of the elements with that page id, and for each of the elements it should select all of the content rows with the element id.

我想对页面进行一次选择,该页面将依次选择具有该页面 id 的所有元素,并且对于每个元素,它应该选择具有元素 id 的所有内容行。

I want to have a static load_by_route($route)function in the Page model that, when called, will use the route to load and return the page info as well as the elements and content as described above. Ideally it would return a single object/array with all of this info.

我想在 Page 模型中有一个静态load_by_route($route)函数,当调用该函数时,将使用该路由来加载和返回页面信息以及如上所述的元素和内容。理想情况下,它会返回一个包含所有这些信息的对象/数组。

Basically, I'm not sure how to chain the has_many() calls together so that I get the two-level relationship.

基本上,我不确定如何将 has_many() 调用链接在一起,以便获得两级关系。

回答by Collin James

Look into eager loading. This should do what you want.

看看急切加载。这应该做你想做的。

class Page extends Eloquent {

    public function elements()
    {
        return $this->has_many( 'Element' );
    }

}

class Element extends Eloquent {

    public function contents()
    {
        return $this->has_many( 'Content' );
    }

}

class Content extends Eloquent {}

$page = Page::with( array( 'elements', 'elements.contents' ) )->first();

https://laravel.com/docs/master/eloquent-relationships#eager-loading

https://laravel.com/docs/master/eloquent-relationships#eager-loading

回答by Adam

Collin James answer gives you one object with all the data. I came here because I just wanted to iterate over all contentsthat belong to a page. Here is how you get such a collection:

Collin James 的回答为您提供了一个包含所有数据的对象。我来这里是因为我只是想遍历contents属于一个页面的所有内容。以下是您如何获得此类收藏:

  $page = Page::with('elements.contents.element')->has('elements.contents');

  $contents = [];
  foreach ($page->elements as $element) {
    $contents = $element->contents->merge($temp);
  }

The withmakes sure that you use eager loadingand the hasmakes sure that we only iterate over elements with content.

with确保使用使得预先加载has肯定,使我们只能重复的进行内容元素

From each content element you can get the element info from the belongsTorelationship that we also received with eager loading:

从每个内容元素中,您都可以从belongsTo我们通过预先加载收到的关系中获取元素信息:

class Content extends Eloquent 
{

 public function element()
 {
    returh $this->belongsTo('\App\Page');
 }

}