Laravel, wie fügt man eine benutzerdefinierte Funktion in einem Eloquent-Modell hinzu?

Lesezeit: 3 Minuten

Ich habe ein Produktmodell

class Product extends Model
{
    ...

    public function prices()
    {
        return $this->hasMany('App\Price');
    }

    ...
}

Ich möchte eine Funktion hinzufügen, die den niedrigsten Preis zurückgibt, und im Controller kann ich den Wert abrufen mit:

Product::find(1)->lowest;

Ich habe dies in Produktmodell hinzugefügt:

public function lowest()
{
    return $this->prices->min('price');
}

aber ich bekam einen Fehler, der besagt:

Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation

Und wenn ich benutze Product::find(1)->lowest();, es wird klappen. Ist es möglich zu bekommen Product::find(1)->lowest; arbeiten?

Jede Hilfe wäre willkommen.

  • nein ofc, weil Sie eine Methode aufrufen, von der ich denke, dass tgat nur für eine hasone-Beziehung funktioniert, und was ist der Unterschied? mit oder ohne!

    – Achraf Khouadja

    8. Juni 2016 um 3:15


Benutzeravatar von Rahul M
Raul M

Wenn Sie versuchen, auf eine Funktion im Modell als Variable zuzugreifen, geht Laravel davon aus, dass Sie versuchen, ein verwandtes Modell abzurufen. Sie nennen sie dynamische Eigenschaften. Stattdessen benötigen Sie ein benutzerdefiniertes Attribut.

Vor Laravel9

Laravel 6-Dokumentation: https://laravel.com/docs/6.x/eloquent-mutators

Fügen Sie Ihrem Modell folgende Methode hinzu:

public function getLowestAttribute()
{
    //do whatever you want to do
    return 'lowest price';
}

Jetzt sollten Sie wie folgt darauf zugreifen können:

Product::find(1)->lowest;

BEARBEITEN: Neu in Laravel 9

Laravel 9 bietet einen neuen Umgang mit Attributen:

Dokumente: https://laravel.com/docs/9.x/eloquent-mutators#accessors-and-mutators

// use Illuminate\Database\Eloquent\Casts\Attribute;

public function lowest(): Attribute
{
     return new Attribute(
        get: function( $originalValue ){
         //do whatever you want to do
         //return $modifiedValue;
      });

     /**
      * Or alternatively:-
      *
      * return Attribute::get( function( $originalValue ){
      *    // do whatever you want to do
      *    // return $modifiedValue;
      * });
      */
}

  • Mir war nicht klar, dass Sie dies mit Attributen tun können, die nicht als Spalten in der zugrunde liegenden Tabelle definiert sind. In der Dokumentation wurde das nicht erwähnt (die ich finden konnte).

    – Aaron Wallentine

    29. November 2016 um 6:21 Uhr

  • Hallo Mich würde auch interessieren wo ich das in der Laravel Dokumentation finden könnte. Vielen Dank.

    – Schleifmaschinen

    24. Januar 2017 um 21:26 Uhr

  • Ich denke, das muss am niedrigsten sein (); — ich erhalte einen Beziehungsfehler ohne die Endung ‘()’

    – Karo

    16. April 2017 um 21:14 Uhr

  • @sanders findest du unter Eloquent: Mutatoren

    – egvaldes

    20. April 2017 um 7:36 Uhr

  • Also im Grunde müssen Sie tun get + Eigenschaftsname-mit-großgeschriebenem-Anfangsbuchstaben + Attribute() um zu bekommen, was du willst? Das ist verwirrend, funktioniert aber. Vielen Dank.

    – HartleySan

    19. März 2019 um 21:11 Uhr

Verwenden Sie Eloquent Accessoren

public function getLowestAttribute()
{
    return $this->prices->min('price');
}

Dann

$product->lowest;

Sie können die obigen Methoden verwenden oder die folgende Methode verwenden, um eine Funktion direkt in das vorhandene Modell einzufügen:

class Company extends Model
{
    protected $table="companies";

    // get detail by id
    static function detail($id)
    {
        return self::find($id)->toArray();
    }

    // get list by condition
    static function list($name="")
    {
        if ( !empty($name) ) return self::where('name', 'LIKE', $name)->get()->toArray();
        else return self::all()->toArray();
    }
}

Oder verwenden Sie Illuminate\Support\Facades\DB; innerhalb Ihrer Funktion. Hoffe, das hilft anderen.

  • Wie greifen Sie auf diese Methoden zu? Ist es Company::detail(2); oder Company::list('Company 1')?

    – Hammermann6006

    17. Juli 2020 um 9:59 Uhr

  • @HalfMens ja, versuche das

    – May’Habit

    18. Juli 2020 um 10:16 Uhr

  • Vielen Dank. Die Hauptsache ist, dass die Methode sein sollte static andernfalls erhalten Sie einen Fehler: Non-static method App\Models\Company::detail(2) should not be called statically

    – Hammermann6006

    18. Juli 2020 um 11:47 Uhr

  • Klar, wenn du direkt anrufen willst. Andernfalls ist Company::where()->detail() oder eine andere statische Methode in Laravel verfügbar.

    – May’Habit

    20. Juli 2020 um 3:00 Uhr

Benutzeravatar von Achraf Khouadja
Achraf Khouadja

warum machst du das einfach nicht Ich weiß, es ist nicht das, wonach Sie ausdrücklich gefragt haben, und es kann manchmal eine schlechte Praxis sein. aber in deinem Fall finde ich es gut.

$product = Product::with(['prices' => function ($query) {
   $query->min('price');
}])->find($id);

Folgecode ändern

public function lowest()
{
    return $this->prices->min('price');
}

zu

// add get as prefix and add posfix Attribute and make camel case function
public function getLowestAttribute()
{
    return $this->prices->min('price');
}

1434110cookie-checkLaravel, wie fügt man eine benutzerdefinierte Funktion in einem Eloquent-Modell hinzu?

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

Privacy policy