拉拉维尔 - 雄辩的关系有很多,但也有一个?



我一直在网上,为此苦苦挣扎了大约 2 个小时。

我有一个用户模型,一个运行模型和一个时间模型。

在现实世界中,用户处于竞赛中,并将他们的时间与USER_id和RUN_id一起输入到数据库中。

对于每个RUN_id,用户应该只能在 TIMES 表中拥有一行 - 如果这有意义的话!

这是我需要在控制器级别管理的内容吗?或者我可以设置关系以确保此样式的重复条目无法进入数据库?

目前的数据库结构:


用户:

名字


运行:

名字


次:

时间

user_id

run_id


模型:

用户:

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

跑:

<?php
namespace App;
use IlluminateDatabaseEloquentModel;
class Run extends Model
{    
public function user()
{
return $this->belongsTo(User::class);
}
public function times()
{
return $this->hasMany(Time::class);
}
}

时间:

<?php
namespace App;
use IlluminateDatabaseEloquentModel;
class Time extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function run()
{
return $this->belongsTo(Run::class);
}
}

您可以在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 进行筛选。messages 函数还会返回更有用的错误消息,因为在这种情况下,"user_id必须是唯一的"是没有帮助的。

这个答案应该补充公认的答案。您仍应将 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

您可以查看文档以获取更多信息

相关内容

  • 没有找到相关文章

最新更新