【问题标题】:getting the value of an extra pivot table column laravel获取额外数据透视表列 laravel 的值
【发布时间】:2014-12-21 09:34:10
【问题描述】:

我有一个 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);

所有这些都是从他们的 slug 中选择特定的模型和问题。

然后我所做的就是使用这些凭据我得到这样的价格:

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

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

【问题讨论】:

    标签: php mysql laravel many-to-many pivot-table


    【解决方案1】:

    Laravel 5.8~

    如果您想制作自定义枢轴模型,可以这样做:

    帐户.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-&gt;users,它具有带有标准列 account_iduser_idaccount_user 连接表。

    如果您制作自定义数据透视模型,您可以将属性和修改器添加到关系的列中。在上面的示例中,一旦创建了 AccountUserPivot 模型,您就可以通过 -&gt;using(AccountUserPivot::class) 指示您的 Account 模型使用它。

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

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

    【讨论】:

    • 谢谢我的朋友
    【解决方案2】:

    从数据透视表获取数据:

    $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 Read more. 中工作

    【讨论】:

    • 理想情况下更新最好还是使用updateExistingPivot()。此外,在 Laravel 5.6 中,可以使用 syncWithoutDetaching() 函数,而不是将 false 作为第二个参数传递给 sync()
    【解决方案3】:

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

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

    Official Docs

    如果您在使用 Eloquent 配置关系方面需要更多帮助,请告诉我。

    编辑

    要查询价格这样做

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

    【讨论】:

    • 我更新了我的问题,让你看看我的关系
    • 有人可以展示如何根据额外的列查询数据透视表,例如上面的示例中的price $model-&gt;problems()-&gt;where('phone_problem', $problem-&gt;id)-&gt;first()-&gt;pivot-&gt;price
    • 不获取而是设置该数据透视条目的值,例如价格,怎么样?
    • @Bartu 这应该可以工作:$model-&gt;problems()-&gt;updateExistingPivot($problemId, ['price' =&gt; $newPrice])。如果不是,请提出一个新问题,因为 cmets 并不是真正适合此问题的地方。
    • 它有效,也许你可以添加它以供其他人进一步参考。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-18
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2017-05-17
    相关资源
    最近更新 更多