Миграция 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 ?

Author: Abrar Jahin, 2016-07-06

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);');
}
 13
Author: Michael, 2016-08-24 22:50:44

Я не думаю, что это особенность миграций Laravel. Я думаю, что это то, что должно быть в ваших моделях или логике проверки, если вы не добавите это вручную в MYSQL

Вот что я бы сделал

$this->validate($request, [
    'Salary' => 'max:150000.00',
]);
 4
Author: Ben Clayton, 2016-07-06 11:57:01

Эта функция не включена в класс схемы элементов, поэтому вы не можете сделать это в своем файле миграции.

Но в вашей модели расчета заработной платы вы можете создать мутатор:

class Payroll extends Model{

    public function setSalaryAttribute($value){
        $this->attributes['Salary'] = $value < 150000.00 ? $value : 150000.00;
    }

}

Таким образом, когда создается или обновляется атрибут заработной платы, этот метод будет автоматически активирован и проверит, что новое значение не превышает 150000,00

РЕДАКТИРОВАТЬ: Вам следует ознакомиться с документацией по мутаторам в документах Laravel.

 2
Author: Gerard Reches, 2016-07-06 12:11:27

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');
}
 1
Author: Kael Watts-Deuchar, 2017-07-26 22:07:34