Laravel> 使用 Eloquent 查询多对多关系
Laravel> Using Eloquent Querying many-to-many relations
我想弄清楚 Eloquent 是如何工作的,以及使用普通 sql 查询的优势(在 columA.id = 上加入 A 和 B tables columnB.id...)
我有两个模型:多对多关系中的渠道和子类别
我创建了一个 channel_subcategory 枢轴 table 并添加了这样的关系:
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文档,他们总是解释迁移,如何在模型中建立关系(belongstomany),甚至如何保存相关数据。但是我在任何地方都找不到一个单一的描述(对于傻瓜),现在让我们从两个 table 中获取一些数据,例如:
- 获取一个频道所属的所有类别。
- 获取一个类别中的所有频道
- 获取属于多个类别的所有频道
- 获取频道较多的类别。
换句话说,关于如何执行此操作的简单说明。
编辑
添加我的频道模型
public function subcategory()
{
return $this->belongsToMany('App\Subcategory')->withTimestamps();
}
您需要在模型中定义关系。在您的情况下,您应该在 Channel
模型中创建一个 subcategories
关系。
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();
我想弄清楚 Eloquent 是如何工作的,以及使用普通 sql 查询的优势(在 columA.id = 上加入 A 和 B tables columnB.id...)
我有两个模型:多对多关系中的渠道和子类别
我创建了一个 channel_subcategory 枢轴 table 并添加了这样的关系:
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文档,他们总是解释迁移,如何在模型中建立关系(belongstomany),甚至如何保存相关数据。但是我在任何地方都找不到一个单一的描述(对于傻瓜),现在让我们从两个 table 中获取一些数据,例如:
- 获取一个频道所属的所有类别。
- 获取一个类别中的所有频道
- 获取属于多个类别的所有频道
- 获取频道较多的类别。
换句话说,关于如何执行此操作的简单说明。
编辑 添加我的频道模型
public function subcategory()
{
return $this->belongsToMany('App\Subcategory')->withTimestamps();
}
您需要在模型中定义关系。在您的情况下,您应该在 Channel
模型中创建一个 subcategories
关系。
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();