Laravel Eltern-Kind-Beziehung nach dem gleichen Modell

Lesezeit: 3 Minuten

Amos Benutzeravatar
Amo

Die Setup- und Dummy-Daten

Ich habe ein einfaches Modell namens Kategorie, das das folgende Schema hat:

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

Die gewünschte Ausgabe

Sie können also sehen, dass wir eine sehr einfache Hierarchie wie folgt erhalten würden:

Home
  - Products
      - Product A
      - Product B
  - Services

Die Angelegenheit

Ich versuche, diese Beziehung in Laravel 4.2 abzubilden, damit ich ein Modell abfragen und seine übergeordneten (es wird immer eine übergeordnete) und untergeordnete Kategorie abrufen kann, falls vorhanden.

Ich habe die Beziehung im Kategoriemodell definiert mit:

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

Das Problem

Ich kann den übergeordneten Namen mithilfe von zum Laufen bringen

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

Ich verstehe jedoch nicht, wie ich die untergeordneten Objekte abrufen kann.

Ich habe es versucht:

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

Aber wenn ich dd($children) ausführe, wird nicht das ausgegeben, was ich erwarten würde.

  • Was ist die Ausgabe von $children?

    – DouglasDC3

    7. Januar 2015 um 10:07 Uhr

Benutzeravatar von lukasgeiter
Lukasgeiter

Aufruf der Beziehungsfunktion (->children()) gibt eine Instanz der Beziehungsklasse zurück. Entweder du musst dann anrufen get() oder verwenden Sie einfach die Eigenschaft:

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

Weitere Erklärung

Eigentlich children() und children sind etwas ganz anderes. children() ruft einfach die Methode auf, die Sie für Ihre Beziehung definiert haben. Die Methode gibt ein Objekt von zurück HasMany. Damit können Sie weitere Abfragemethoden anwenden. Zum Beispiel:

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

Jetzt Zugriff auf die Eigentum children funktioniert anders. Du hast es nie definiert, also zaubert Laravel im Hintergrund.

Schauen wir uns mal an Illuminate\Database\Eloquent\Model:

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

Das __get Die Funktion wird aufgerufen, wenn Sie versuchen, auf eine Eigenschaft eines PHP-Objekts zuzugreifen, das nicht wirklich existiert.

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);
    }
}

Dann in getAttribute Zuerst ist ein Code, der nach “normalen” Attributen sucht und dann zurückgibt. Und schließlich am Ende der Methode, wenn eine Beziehungsmethode definiert ist getRelationshipFromMethod wird genannt.

Es wird dann das Ergebnis der Beziehung abrufen und zurückgeben.

  • Ok, die Klammern beim Aufruf der Kinder sind in diesem Fall also nicht erforderlich. Etwas verwirrend in einem ansonsten sehr schönen Rahmen, aber das hat das Problem gelöst. Vielen Dank.

    – Amo

    7. Januar 2015 um 10:13 Uhr

  • Nicht wirklich .. Ich habe meine Antwort mit einer Erklärung aktualisiert 🙂

    – Lukasgeiter

    7. Januar 2015 um 10:22 Uhr

  • Perfekt! Vielen Dank für die sehr ausführliche Erklärung.

    – Amo

    7. Januar 2015 um 10:42 Uhr

Stellen Sie dies im Modell ein und versuchen Sie Folgendes:

public function children()
{
    return $this->hasMany(self::class, 'parent_id');
}

public function grandchildren()
{
    return $this->children()->with('grandchildren');
}

  • Affarin, Eyval 😉

    – Dol Durma

    27. August 2021 um 7:18 Uhr

  • khahesh 🙂 @DolDurma

    – Zahra Badri

    28. August 2021 um 6:10 Uhr

  • Adam eftekhar mikone ist in javanan irani 🙂

    – Mostafa Norzade

    28. Oktober 2021 um 8:48 Uhr

  • @MostafaNorzade mamnoonam 🙂

    – Zahra Badri

    30. Oktober 2021 um 8:38 Uhr

1403550cookie-checkLaravel Eltern-Kind-Beziehung nach dem gleichen Modell

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy