Laravel>使用Eloquent查询多对多关系

时间:2017-06-02 05:43:33

标签: laravel eloquent many-to-many querying

我试图找出Eloquent如何工作以及使用普通sql查询的优势(在columA.id = columnB.id上加入A和B表...)

我有两个模型:多对多关系中的频道和子类别

我创建了一个channel_subcategory数据透视表,并添加了这样的关系:

public function up()
{
    Schema::create('channel_subcategory', function (Blueprint $table) {
        $table->increments('id');
        $table->timestamp('created_at')->useCurrent();
        $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
        $table->integer('channel_id')->unsigned()->nullable();
        $table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
        $table->integer('subcategory_id')->unsigned()->nullable();
        $table->foreign('subcategory_id')->references('id')->on('subcategories') ->onDelete('cascade');
    });
}


I want to get one channel given the slug property and the subcategories it belongs to. So I did this in the ChannelController.php

 public function show($slug)
{
    $channel = Channel::where('channels.slug', '=', $slug)->first();
    foreach ($channel as $subcategory) {
        echo $subcategory->title;
    }
}

I get the error:

ErrorException in ChannelController.php line 107: Trying to get property of non-object


All I want is to show the channel name and the categories it belongs to.

我已经阅读了很多博客,包括Laravel文档,它们总是解释迁移,如何在模型中建立关系(belongsstomany),甚至如何保存相关数据。但是我找不到一个单独的描述(对于傻瓜),现在让我们从两个表中获取一些数据,如:

  • 获取一个频道所属的所有类别。
    • 获取一个类别中的所有频道
    • 获取属于多个类别的所有频道
    • 获取更多频道的类别。

换句话说,就如何做到这一点的简单解释。

修改 添加我的频道模型

public function subcategory()
{
    return $this->belongsToMany('App\Subcategory')->withTimestamps();
}

1 个答案:

答案 0 :(得分:1)

您需要在模型中定义关系。在您的情况下,您应该在subcategories模型中创建Channel关系。

public function subcategories()
{
    return $this->belongsToMany(Subcategory::class, 'channel_subcategory', 'channel_id', 'subcategory_id')->withTimestamps();
}

SubCategory更改为您已为模型命名的任何内容。

然后在您的控制器中,您可以访问这样的关系

$channel = Channel::where('slug', $slug)->first();

foreach ($channel->subcategories as $subcategory) {
    echo $subcategory->title;
}

虽然上面的代码有效,但如果你需要关系数据,你应该总是急于加载。这可以防止N + 1查询问题。

$channel = Channel::with('subcategories')->where('slug', $slug)->first();