我已经遍及网络了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);
}
}
答案 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以获得更多信息