CONSOLAIN在Laravel 5 Schema Builder上独一无二

Iva*_*los 5 php orm laravel eloquent laravel-5

首先,我想告诉你,我已经在互联网上搜索了这个问题,但我无法解决这个问题.

我的问题是我的表的主键.

我有2个表,事件event_guest

+-----------+
| event     |
+-----------+
| eventid   |
+-----------+

+-------------+
| event_guest |
+-------------+
| guestid     |
| eventid     |
| firstname   |
| lastname    |
| email       |
+-------------+
Run Code Online (Sandbox Code Playgroud)

每个活动都有很多event_guest,但每个活动的电子邮件必须是唯一的.

在我的控制器上,我想通过在EventGuest模型上使用firstOrCreate方法来获取或创建:

EventGuests::firstOrCreate(['eventid' => $eventid,'firstname' => 'Ivan', 'lastname'=>'Bravo', 'email'=>'ivnbrv@mac.com');
Run Code Online (Sandbox Code Playgroud)

如果未在事件中设置电子邮件,则必须记录该条目.

+-----------+----------+-----------+-----------+----------------+
|  guestid  | eventid  | firstname | lastname | email           | 
+-----------+----------+-----------+-----------+----------------+
|         1 |        1 | Ivan      | Bravo     | ivnbrv@mac.com | 
+-----------+----------+-----------+-----------+----------------+
Run Code Online (Sandbox Code Playgroud)

我需要的是eventid作为主键,guestidauto_increment字段,以便它可以重置为1对每个事件.例如:

+-----------+----------+-----------+-----------+----------------+
|  guestid  | eventid  | firstname | lastname | email           | 
+-----------+----------+-----------+-----------+----------------+
|         1 |        1 | Ivan      | Bravo     | ivnbrv@mac.com | 
|         2 |        1 | John      | Doe       | test@mac.com   | 
|         1 |        2 | Ivan      | Bravo     | ivnbrv@mac.com | 
+-----------+----------+-----------+-----------+----------------+
Run Code Online (Sandbox Code Playgroud)

并且我还需要电子邮件作为唯一字段来防止重复行.

目前我正在使用Laravel 5 Migrations,但是当我尝试重置主要字段时,它会提示此错误:

Multiple primary key defined (SQL: alter table `event_guest` add primary key event_guest_eventid_guestid_primary(`eventid`, `guestid`))                            
Run Code Online (Sandbox Code Playgroud)

这是我的迁移代码:

    Schema::create('event_guest', function(Blueprint $table) {
                $table->integer('guestid', true);
                $table->integer('eventid');
                $table->integer('contactid')->nullable();
                $table->string('firstname', 256);
                $table->string('lastname', 256);
                $table->string('email', 256);
                $table->unique( array('email','name') );
                $table->primary(array('eventid','guestid'));

            });
Run Code Online (Sandbox Code Playgroud)

我真的需要帮助来正确理解这一点.

我过去没有遇到任何麻烦:

create table `event_guest` (
    `guestid` int(11) NOT NULL AUTO_INCREMENT,
    `eventid` int(11) NOT NULL DEFAULT '0',
    `firstname` varchar(255) NOT NULL,
    `lastname` varchar(255) NOT NULL,
    `email` varchar(255) NOT NULL,
    PRIMARY KEY (`eventid`,`guestid`),
    CONSTRAINT guest UNIQUE (eventid,email)
) ENGINE=MyISAM
Run Code Online (Sandbox Code Playgroud)

现在

jed*_*ylo 2

您的迁移代码有两个问题,导致您无法创建所需的表。

首先,默认的MySQL引擎是InnoDB,它不允许复合主键自动递增。因此,您需要显式地将引擎设置为MyISAM:

$table->engine = 'MyISAM';
Run Code Online (Sandbox Code Playgroud)

其次,当您将列设置为自动增量时,Laravel 的模式构建器会假定它是主键,并在生成 create 语句时将该列设为主键。因此,当下一个查询尝试定义复合主键时,guestid 列上已经存在主键 - 因此出现重复主键错误。

该问题的解决方案是将 guestid 定义为标准整数列,创建复合键,然后更新 guestid 列,使其自动增量。不幸的是,模式生成器不支持除重命名列之外的任何更改操作,因此您需要使用底层数据库层并执行原始查询。

总而言之,您的迁移代码应如下所示:

Schema::create('event_guest', function(Blueprint $table) {
    $table->engine = 'MyISAM';
    $table->integer('guestid');
    $table->integer('eventid');
    $table->integer('contactid')->nullable();
    $table->string('firstname', 256);
    $table->string('lastname', 256);
    $table->string('email', 256);
    $table->unique( array('email','name') );
    $table->primary(array('eventid','guestid'));
});

DB::statement('ALTER TABLE event_guest MODIFY guestid INTEGER NOT NULL AUTO_INCREMENT');
Run Code Online (Sandbox Code Playgroud)