Laravel-雄辩的关系hasMany但也hasOne?

时间:2019-12-17 15:02:29

标签: laravel eloquent laravel-6.2

我已经遍及网络了2个小时左右。

我有一个USER模型,一个RUN模型和一个TIME模型。

在现实世界中,用户参加比赛时,会将他们的时间以及USER_id和RUN_id一起输入数据库。

对于每个RUN_id,用户只能在TIMES表中有一行-这样做是有道理的!

这是我需要在控制器级别进行管理的东西吗?还是可以建立一种关系来确保这种样式的重复条目不能进入数据库?

目前的数据库结构:


用户:

名称


运行:

名称


时间:

时间

user_id

run_id


模型:

用户:

public function times()
{
    return $this->hasMany(Time::class);
}

运行:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Run extends Model
{    
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function times()
    {
        return $this->hasMany(Time::class);
    }
}

时间:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Time extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function run()
    {
        return $this->belongsTo(Run::class);
    }

}

2 个答案:

答案 0 :(得分:2)

您可以在times表上添加唯一键约束,以实施user_id和run_id的唯一组合

$table->unique(['user_id, 'run_id']);

要在应用程序级别验证唯一性,我们还可以在表单验证中添加约束。假设您在请求中同时传递了user_id和run_id以创建新时间,则可以将以下内容添加到表单请求中

/**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'user_id' => Rule::unique('times')->where('run_id', $this->input('run_id'))
        ];
    }

    public function messages()
    {
        return [
            'user_id.unique' => 'A user may only have 1 time entry per Run'
        ];
    }

这将强制user_id在times表中是唯一的,并由该运行ID过滤。消息功能还返回一条更有用的错误消息,因为“ user_id必须唯一”在这种情况下无济于事。

答案 1 :(得分:1)

此答案应补充接受的答案。您仍然应该将user_id,run_id对定义为唯一键。 但是,在您的情况下,用户和运行具有times作为数据透视表的N-N关系。您应该这样编码。

用户

public function runs()
{
    return $this->belongsToMany(Run::class, 'times')->withPivot('time');;
}

运行:

public function users()
{
    return $this->belongsToMany(User::class, 'times')->withPivot('time');
}

然后您可以将它们检索为:


$runs = User::find($userId)->runs; // Collection of all runs a user participated in
// $runs[X]->pivot->time has the time

您可以检查the documentation以获得更多信息