Laravel ORM从作者列表中获取所有书籍

时间:2014-04-17 12:25:40

标签: php sql orm laravel

我有一本书的模型和一本作者的模型。 书籍模型具有belongsTo作者关系,作者有很多书籍。

我有一个sql查询给了我一些作者,现在我想把所有这些作者的书籍放在一个列表中。

我以为我可以写:

$authors->books

但这给了我错误

Undefined property: Illuminate\Database\Eloquent\Collection::$books 

我知道我可以致电$author->books如果它是我的单一作者,但如果我喜欢这个案例的作者集合,我怎么能把他们所有的书放在一起呢?

2 个答案:

答案 0 :(得分:2)

由于您正在检索多个作者,因此Laravel将其作为集合返回。您无法查询集合,这意味着您必须使用foreach来运行它。

通过遍历集合

$allBooks = array();

foreach ($authors as $author){
    $authorBooks = $author->books->get()->toArray();
    $allBooks = array_merge($allBooks, $authorBooks);
}

我建议使用范围。

其他解决方案可能正在使用范围:

使用您的作者ID创建一个数组。使用对象时,可以使用 - >列表('id')。 (在这个例子中,我接受了所有作者,但你可以使用 - > gt; where或scope来限制。)

$authorids= Author::all()->lists('id');

在Book模型中创建scopeAuthorIds,如下所示:

public function scopeAuthorIds($query, $ids)
{
return $query->whereIn('authorId', $ids);
}

您应该可以通过

立即过滤作者ID上的图书
$allBooks = Book::AuthorIds($authorids)->get();

答案 1 :(得分:0)

只需使用with('books') eager loading

$authors = Author::with('books')->get();

确保您在Author型号中具有以下功能:

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

使用::with('Book')将解决(较少查询)n+查询(称为急切加载)问题。接下来,您可以使用这样的循环:

foreach($authors as $author) {
    // Assumed you have a name property in authors table
    echo $author->name; // in blade use {{ $author->name }} to echo
    foreach($author->books as $book) {
        // Assumed you have a title property in books table
        echo $book->title; // in blade use {{ $book->title }} to echo
    }
}

如果没有循环,您可以使用以下方法从集合中获取任何模型:

// Assumed 1 is the id here in both cases
$author->find(1)->books->find(1)->title;

或者您可以使用以下内容:

$author->first()->books->first()->title;
$author->first()->books->find(2)->title;

您可以使用get(index)使用该项目的索引从集合中获取项目,如下所示:

// First author model and first book model
$author->get(0)->books->get(0)->title;

请记住,$author是一个集合,$author->books也是一个集合。你可以like this