如何从Laravel 5.8中的嵌套模型返回数据

时间:2019-09-15 02:46:12

标签: laravel laravel-5

我有四个模型用于:国家>图书馆>书籍>章节。每个国家都有多个图书馆,其中有多本书籍由多个章节组成。

使用Laravel 5.8,我如何根据子弹检索特定国家/地区所有图书馆的所有书籍的所有章节的清单?

国家/地区型号:

class Country extends Model
{
    public function libraries() {
        return $this->hasMany(Library::class);
    }
}

库模型:

class Library extends Model
{
    public function country() {
        return $this->belongsTo(Country::class);//country_id
    }

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

图书模型:

class Book extends Model
{    
    public function library() {
        return $this->belongsTo(Library::class);//library_id
    }

    public function chapters() {
        return $this->hasMany(Chapter::class);
    }
}

章节模型:

class Chapter extends Model
{   
    public function book() {
        return $this->belongsTo(Book::class);//book_id
    }
}

我一直尝试按以下方式检索数据,但未成功:

CountryController:

namespace App\Http\Controllers;

use App\Country;
use App\Http\Controllers\Controller;

class CountryController extends Controller
{
    public function show($slug)
    {    
        $country = Country::where('slug', $slug)->first();
        $chapters = $country->with('libraries.books.chapters');
        dd($chapters);
    }

    public function getRouteKeyName()
    {
        return 'slug';
    }
}

路由器:

Route::get('/countries/{slug}', 'CountryController@show');

我没有得到特定的错误,但是返回的数据不存在。当我在返回的转储中展开#model时,我看到了exists: false,尽管急切的加载似乎是正确的。

Builder {#217 ▼
  #query: Builder {#213 ▶}
  #model: Country {#218 ▶}
  #eagerLoad: array:3 [▼
    "libraries" => Closure() {#221 ▶}
    "libraries.books" => Closure() {#224 ▶}
    "libraries.books.chapters" => Closure() {#220 ▶}
  ]
  #localMacros: []
  #onDelete: null
  #passthru: array:17 [▶]
  #scopes: []
  #removedScopes: []
}

2 个答案:

答案 0 :(得分:0)

我认为您应该从最外部的模型开始。在这种情况下,Chapter。因此,要从X国家/地区的图书中获取所有章节,您可以使用以下代码:

Chapter::whereHas('book.library.country', function($q) use ($slug){
  $q->where('slug', $slug)
})

如果您从内到外考虑如何执行SQL查询,那么上面的查询构建器将更有意义。来自闭包的查询将首先执行。

答案 1 :(得分:0)

我认为您需要为此使用查询生成器: 我尚未对此进行测试,但可能会起作用:

$chapters = DB::table('chapters')
        ->join('books', 'chapters.book_id', '=', 'books.id')
        ->join('libraries', 'books.library_id', '=', 'libraries.id')
        ->join('countries', 'libraries.country_id', '=', 'countries.id')
        ->select('chapters.*')
        ->get();