获取额外的数据透视表列laravel的值


71

我有一个phone_models,phone_problems和一个phone_model_phone_problem数据透视表。数据透视表有一个额外的“价格”列。

手机型号:

class PhoneModel extends \Eloquent
{
    public function problems()
    {
        return $this->belongsToMany('RL\Phones\Entities\PhoneProblem')->withPivot('price');
    }
}

电话问题:

class PhoneProblem extends \Eloquent
{
    public function models()
    {
        return $this->belongsToMany('PhoneModel')->withPivot('price');
    }
}

我想做的是获取具有特定问题的特定手机的价格。

这就是我现在的方式,但是我觉得Laravel具有内置的Eloquent功能,我找不到用更简单的方式做到这一点:

$model = $this->phoneService->getModelFromSlug($model_slug);
$problem = $this->phoneService->getProblemFromSlug($problem_slug);

这一切都是从他们的中选择特定的模型和问题。

然后我要做的就是凭这些凭证获得价格,如下所示:

$row = DB::table('phone_model_phone_problem')
->where('phone_model_id', '=', $model->id)
->where('phone_problem', '=', $problem->id)
->first();

所以现在我可以得到这样的价格,$row->price但是我觉得需要一种更简单,更“ Laravel”的方式来做到这一点。

Answers:


141

当对Eloquent使用“多对多”关系时,结果模型将自动获得pivot分配的属性。通过该属性,您可以访问数据透视表列。尽管默认情况下,枢轴对象中只有键。为了将列也放入其中,您需要在定义关系时指定它们:

return $this->belongsToMany('Role')->withPivot('foo', 'bar');

官方文件

如果您需要更多与Eloquent配置关系的帮助,请告诉我。

编辑

要查询价格,请执行此操作

$model->problems()->where('phone_problem', $problem->id)->first()->pivot->price

我更新了问题供您查看我的
Rodrigo 2014年

有人可以显示如何根据额外的列查询数据透视表,例如,price在上面的示例中$model->problems()->where('phone_problem', $problem->id)->first()->pivot->price
Brent Connor

不但要设置该枢纽条目的价格(例如价格)怎么办?
巴图2015年

@Bartu应该可以正常工作:$model->problems()->updateExistingPivot($problemId, ['price' => $newPrice])。如果不是,请提出一个新问题,因为评论并非真正合适的地方。
lukasgeiter 2015年

它有效,也许您可​​以添加它以供其他人参考。
巴图2015年

18

要从数据透视表获取数据:

$price = $model->problems()->findOrFail($problem->id, ['phone_problem'])->pivot->price;

或者,如果您有许多价格不同的记录:

$price = $model->problems()->where('phone_problem', $problem->id)->firstOrFail()->pivot->price;

此外。

更新数据透视图中的数据,您可以使用NEW WAY

$model->problems()->sync([$problemId => [ 'price' => $newPrice] ], false); 

如果将第二个参数设置为false,则意味着您不会分离所有其他相关模型。

或者,走旧路

$model->problems()->updateExistingPivot($problemId, ['price' => $newPrice]);

并提醒您:

删除

$model->problems()->detach($problemId);

创建新的:

$model->problems()->attach($problemId, ['price' => 22]);

它已经过测试并证明可在Laravel 5.1中工作


2
理想情况下进行更新仍然更好updateExistingPivot()。另外,在Laravel 5.6falsesync(),可以将syncWithoutDetaching()函数作为第二个参数传递给,而不必使用。
Dim13i '18

3

Laravel 5.8〜

如果要创建自定义枢轴模型,可以执行以下操作:

Account.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Account extends Model
{
    public function users()
    {
        return $this->belongsToMany(User::class)
            ->using(AccountUserPivot::class)
            ->withPivot(
                'status',
                'status_updated_at',
                'status_updated_by',
                'role'
            );
    }
}

AccountUserPivot.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class AccountUserPivot extends Pivot
{
    protected $appends = [
        'status_updated_by_nice',
    ];

    public function getStatusUpdatedByNiceAttribute()
    {
        $user = User::find($this->status_updated_by);

        if (!$user) return 'n/a';

        return $user->name;
    }
}

在上面的示例中,Account您的模型是您的普通模型,并且具有带标准列和$account->usersaccount_user联接表。account_iduser_id

如果创建自定义枢轴模型,则可以将属性和变量添加到关系的列上。在上面的示例中,一旦创建了AccountUserPivot模型,您就可以通过指示您的Account模型使用它->using(AccountUserPivot::class)

然后,您可以访问此处其他答案中显示的所有内容,但也可以通过$account->user[0]->pivot->status_updated_by_nice(假设status_updated_by是users表中ID的外键)访问example属性。

有关更多文档,请参阅https://laravel.com/docs/5.8/eloquent-relationships(我建议按CTRL + F并搜索“数据透视”)


感谢我的朋友
Ali Sharifineyestani
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.