我有两个模型EventLocation
和EventDepartment
。模型和关系如下所示:
class EventLocation extends Model
{
public function event_departments()
{
return $this->hasMany(EventDepartment::class);
}
}
class EventDepartment extends Model
{
public function event_location()
{
return $this->belongsTo(EventLocation::class, 'location_id');
}
}
EventDepartment
的迁移包含location_id
作为外键,如下所示:
Schema::create('event_departments', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->foreignId('location_id')->constrained('event_locations');
$table->softDeletes();
$table->timestamps();
});
我现在面临的问题是,当基于外键EventDepartment
创建新的单位时,如何在location_id
表中使列唯一?
即,如果一个EventDepartment属于相同的EventLocation,则不能具有相同名称的列,但是只要它属于另一个EventLocation,我就可以创建另一个具有现有名称的EventDepartment >
我已经尝试过了,但是没有用:
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required|min:3|unique:event_departments,location_id',
'location_id' => 'required',
]);
$department = EventDepartment::create([
'name' => $request->name,
'location_id' => $request->location_id,
]);
return new EventDepartmentResource($department);
}
答案 0 :(得分:1)
在创建迁移时,您应该通过相关字段设置唯一性。
在您的示例中,应为name
和location_id
public function up()
{
Schema::create('event_departments', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->foreignId('location_id')->constrained('event_locations');
$table->softDeletes();
$table->timestamps();
$table->unique(['name', 'location_id'], 'unique_name_location');
});
}
public function down()
{
Schema::enableForeignKeyConstraints();
Schema::table('event_departments', function (Blueprint $table) {
$table->dropForeign(['location_id']);
$table->dropUnique('unique_name_location');
})
Schema::disableForeignKeyConstraints();
Schema::drop('event_departments');
}
这将确保数据库级别,表的既定规则,并且具有相同location_id的名称不会超过一个。 Docs。
在PHP级别上,您必须编写自己的规则类,该类将触发并检查DB可以接受的规则。
-创建规则类
php artisan make:rule UniqueNameLocationRule
规则类代码
public function __construct(string $name, int $locationId)
{
$this->name = $name;
$this->locationId = $locationId;
}
public function passes($attribute, $value)
{
return !EventDepartment::where([
'name' => $this->name,
'location_id' => $this->locationId,
])->exists();
}
-验证码
'name' => ['bail', 'required', 'min:3', new UniqueNameLocationRule((string)$request->name, (int)$request->location_id)],
'location_id' => ['required', 'exists:event_locations,id'],
Docs。
这应该可行,请测试并确定是否存在错误。
答案 1 :(得分:0)
我认为,在您进行验证时,您的uniqiue属性位于错误的位置。您正在检查代码中“ event_departments表的location_id列中的“ name”变量是否唯一”,但您不想检查名称。您要检查location_id。如果我对您的问题有误,对不起。
$this->validate($request, [
'name' => 'required|min:3',
'location_id' => 'required|unique:event_departments,location_id',
]);
您可以试试吗?或者,如果您想检查姓名,请尝试这个;
$this->validate($request, [
'name' => 'required|min:3|unique:event_departments,name',
'location_id' => 'required',
]);