php 同一模型上的 Laravel 父/子关系

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27816738/
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-08-25 23:32:26  来源:igfitidea点击:

Laravel parent / child relationship on the same model

phplaravel

提问by Amo

The Setup And Dummy Data

设置和虚拟数据

I have a simple model called Category, which has the following schema:

我有一个名为 Category 的简单模型,它具有以下架构:

|----------------------------------------------|
| cat_id   | cat_name    | parent_id           |
|----------------------------------------------|
|   1      | Home        |   0                 |
|----------------------------------------------|
|   2      | Products    |   1                 |
|----------------------------------------------| 
|   3      | Services    |   1                 |
|----------------------------------------------|
|   4      | Product A   |   2                 |
|----------------------------------------------|
|   5      | Product B   |   2                 |
|----------------------------------------------|

The Desired Output

所需的输出

So you can see that we would get a very straight forward hierarchy as follows:

所以你可以看到我们会得到一个非常简单的层次结构,如下所示:

Home
  - Products
      - Product A
      - Product B
  - Services

The Issue

问题

I'm trying to map this relationship in Laravel 4.2, so that I can query a model and get its parent (it will always have a parent), and child categories if they exist.

我试图在 Laravel 4.2 中映射这种关系,以便我可以查询模型并获取其父级(它将始终具有父级)以及子类别(如果存在)。

I've defined the relationship in the Category model using:

我已经使用以下方法定义了 Category 模型中的关系:

public function children()
{
    return $this->hasMany('Category', 'parent_id', 'cat_id');
}
public function parent()
{
    return $this->belongsTo('Category', 'parent_id');
}

The Problem

问题

I can get the parent name working, using

我可以让父名称工作,使用

$category = Category::findOrFail($id);
return $category->parent->cat_name;

However, I don't understand how to get the child objects.

但是,我不明白如何获取子对象。

I've tried:

我试过了:

$category = Category::findOrFail($id);
$children = $category->children();

But when I dd($children) it doesn't output what I'd expect.

但是当我 dd($children) 时,它不会输出我所期望的。

回答by lukasgeiter

Calling the relationship function (->children()) will return an instance of the relation class. You either need to call then get()or just use the property:

调用关系函数 ( ->children()) 将返回关系类的一个实例。您要么需要调用 thenget()要么只使用该属性:

$children = $category->children()->get();
// or
$children = $category->children;

Further explanation

进一步说明

Actually children()and childrenare something pretty different. children()just calls the method you defined for your relationship. The method returns an object of HasMany. You can use this to apply further query methods. For example:

实际上children()children是非常不同的东西。children()只需调用您为关系定义的方法。该方法返回一个对象HasMany。您可以使用它来应用进一步的查询方法。例如:

$category->children()->orderBy('firstname')->get();

Now accessing the propertychildrenworks differently. You never defined it, so Laravel does some magic in the background.

现在访问该属性的children工作方式有所不同。你从来没有定义过它,所以 Laravel 在后台做了一些魔法。

Let's have a look at Illuminate\Database\Eloquent\Model:

让我们来看看Illuminate\Database\Eloquent\Model

public function __get($key)
{
    return $this->getAttribute($key);
}

The __getfunction is called when you try to access a property on a PHP object that doesn't actually exist.

__get当您尝试访问实际不存在的 PHP 对象上的属性时,将调用该函数。

public function getAttribute($key)
{
    $inAttributes = array_key_exists($key, $this->attributes);

    // If the key references an attribute, we can just go ahead and return the
    // plain attribute value from the model. This allows every attribute to
    // be dynamically accessed through the _get method without accessors.
    if ($inAttributes || $this->hasGetMutator($key))
    {
        return $this->getAttributeValue($key);
    }

    // If the key already exists in the relationships array, it just means the
    // relationship has already been loaded, so we'll just return it out of
    // here because there is no need to query within the relations twice.
    if (array_key_exists($key, $this->relations))
    {
        return $this->relations[$key];
    }

    // If the "attribute" exists as a method on the model, we will just assume
    // it is a relationship and will load and return results from the query
    // and hydrate the relationship's value on the "relationships" array.
    $camelKey = camel_case($key);

    if (method_exists($this, $camelKey))
    {
        return $this->getRelationshipFromMethod($key, $camelKey);
    }
}

Then in getAttributefirst is some code that checks for "normal" attributes and returns then. And finally, at the end of the method, if there's a relation method defined getRelationshipFromMethodis called.

然后getAttribute首先是一些检查“正常”属性然后返回的代码。最后,在方法结束时,如果定义了一个关系方法,getRelationshipFromMethod则调用。

It will then retrieve the result of the relationship and return that.

然后它将检索关系的结果并返回。