【问题标题】:How to return data from nested models in Laravel 5.8如何从 Laravel 5.8 中的嵌套模型返回数据
【发布时间】:2019-09-16 14:28:50
【问题描述】:

我有四个模型:国家 > 图书馆 > 书籍 > 章节。每个国家/地区都有多个图书馆,这些图书馆拥有多本由多个章节组成的书籍。

使用 Laravel 5.8,如何根据 slug 检索特定国家所有图书馆的所有书籍的所有章节列表?

国家模式:

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

我一直在尝试按如下方式检索数据,但没有成功:

国家控制器:

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: []
}

【问题讨论】:

  • 您甚至没有获取记录。例如:$chapters->get()。您是想只获取章节还是所有中间模型?
  • @Pablo ->get() 引发 SQL 错误。只是试图获得章节。
  • 分享错误肯定会有所帮助:)
  • 您的问题可以通过“有很多通过”来解决:laravel.com/docs/master/eloquent-relationships#has-many-through
  • @HadiAghandeh 调查了这个,但它没有深入 4 层。

标签: laravel laravel-5


【解决方案1】:

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

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

如果您认为 SQL 查询是如何从内到外执行的,那么上面的查询构建器会更有意义。闭包中的查询将首先执行。

【讨论】:

    【解决方案2】:

    我认为您需要为此目的使用查询生成器: 我没有对此进行测试,但它可能会起作用:

    $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();
    

    【讨论】:

    • 谢谢,但我希望模型能够指示查询并尊重其关系/。
    猜你喜欢
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    相关资源
    最近更新 更多