Миграция Laravel - Добавление Контрольных Ограничений В Таблицу
Я хочу создать таблицу в миграции Laravel следующим образом -
CREATE TABLE Payroll
(
ID int PRIMARY KEY,
PositionID INT,
Salary decimal(9,2)
CHECK (Salary < 150000.00)
);
То, что я сделал, это -
Schema::create('Payroll', function (Blueprint $table)
{
$table->increments('id');
$table->integer('PositionID ');
$table->decimal('Salary',9,2);
//$table->timestamps();
});
Но я не могу создать это -
CHECK (Salary < 150000.00)
Может ли кто-нибудь, пожалуйста, рассказать, как реализовать эти CHECK
ограничения в Миграции Laravel ?
4 answers
Добавление ограничений не поддерживается классом Blueprint (по крайней мере, начиная с Laravel 5.3), однако возможно добавлять ограничения в ваши таблицы непосредственно из ваших миграций, используя инструкции базы данных.
В вашем файле миграции
public function up ()
{
Schema::create('payroll', function (Blueprint $table) {
$table->increments('id');
$table->integer('position_id');
$table->decimal('salary',9,2);
});
// Add the constraint
DB::statement('ALTER TABLE payroll ADD CONSTRAINT chk_salary_amount CHECK (salary < 150000.00);');
}
Я не думаю, что это особенность миграций Laravel. Я думаю, что это то, что должно быть в ваших моделях или логике проверки, если вы не добавите это вручную в MYSQL
Вот что я бы сделал
$this->validate($request, [
'Salary' => 'max:150000.00',
]);
Эта функция не включена в класс схемы элементов, поэтому вы не можете сделать это в своем файле миграции.
Но в вашей модели расчета заработной платы вы можете создать мутатор:
class Payroll extends Model{
public function setSalaryAttribute($value){
$this->attributes['Salary'] = $value < 150000.00 ? $value : 150000.00;
}
}
Таким образом, когда создается или обновляется атрибут заработной платы, этот метод будет автоматически активирован и проверит, что новое значение не превышает 150000,00
РЕДАКТИРОВАТЬ: Вам следует ознакомиться с документацией по мутаторам в документах Laravel.
MySQL/Mariadb игнорируют ограничения CHECK
, поэтому вместо этого вам придется использовать триггеры. Триггеры могут быть настроены только для запуска в одном из вариантов ВСТАВКИ/ОБНОВЛЕНИЯ/УДАЛЕНИЯ, что означает, что если мы хотим, чтобы он выполнялся как при ВСТАВКЕ, так и при ОБНОВЛЕНИИ, мы должны создать процедуру, а затем вызвать ее из двух отдельных триггеров.
DB::оператор() не поддерживает этот синтаксис, поэтому вместо этого мы должны использовать PDO::exec().
Вот синтаксис TRIGGER
для примера Майкла:
public function up()
{
Schema::create('Payroll', function (Blueprint $table) {
$table->increments('id');
$table->integer('position_id');
$table->decimal('salary', 9, 2);
});
DB::connection()->getPdo()->exec("
-- Create the procedure
CREATE PROCEDURE payroll_check_salary_amount (salary INT)
BEGIN
IF NOT (salary < 150000.00) THEN
SIGNAL SQLSTATE '45000' SET message_text = 'salary must be less than 150000.00';
END IF;
END;
-- Create the INSERT trigger
CREATE TRIGGER payroll_check_salary_amount_insert BEFORE INSERT ON Payroll
FOR EACH ROW
BEGIN
CALL payroll_check_salary_amount(NEW.salary);
END;
-- Create the UPDATE trigger
CREATE TRIGGER payroll_check_salary_amount_update BEFORE UPDATE ON Payroll
FOR EACH ROW
BEGIN
CALL payroll_check_salary_amount(NEW.salary);
END;
");
}
public function down()
{
Schema::dropIfExists('Payroll');
DB::statement('DROP PROCEDURE IF EXISTS payroll_check_salary_amount');
}