Returning the first model from a hasMany relations

2019-06-03 23:20发布

问题:

Is it possible to create a quick method to return the first model from a one-to-many relationship? Here is my code, from the model file:

public function books() {
    return $this->hasMany('App\Models\Book');
}

public function first_book() {
    return $this->book()->first();
}

This is the error I'm getting:

'Call to undefined method Illuminate\Database\Query\Builder::addEagerConstraints()'

The reason I want to use this is so that I can collect the first record using the with() method, for example:

    $authors = Author::with('first_book')->select('*');

I'm using these records with Datatables.

回答1:

I might be late but for your future use and for other who want the same output try this one -

// If you need the last one

public function books() {
    return $this->hasOne('App\Models\Book')->latest();
}

// If you need the first entry -

public function books() {
        return $this->hasOne('App\Models\Book')->oldest();
    }


回答2:

A relation that can be eager loaded has to return a query. The first() function returns an eloquent object.

The solution is to limit the number of results of this query like so:

public function first_book() {
    return $this->books()->take(1);
}

$author->first_book will still be a collection, but it will only contain the first related book in your database.



回答3:

To use with() your method has to return a collection from a relation method, because your relation is hasMany. So what you could do is:

public function books() {
    return $this->hasMany('App\Models\Book');
}

public function first_book() {
    return $this->hasMany('App\Models\Book')->limit(1);
}

Which would return a collection with your first item, so you' still have to call first():

$authors = Author::with('first_book')->select('*');
$authors->first_book->first();


回答4:

A one-to-one relationship is a very basic relation. For example

public function books()
    {
        return $this->hasOne('App\Models\Book');
    }