首先,我想告诉你,我在网上搜索了这个问题,也没有能够解决这个问题。
我的问题是我的表的主键。
我有 2 个表,events 和 event_guest
+-----------+
| event |
+-----------+
| eventid |
+-----------+
+-------------+
| event_guest |
+-------------+
| guestid |
| eventid |
| firstname |
| lastname |
| email |
+-------------+
每个事件都有多个event_guest
,但每个事件的每个客人的电子邮件必须是唯一的。
在我的 Controller 上,我想通过在 EventGuest 模型上使用 firstOrCreate 方法来获取或创建:
EventGuests::firstOrCreate(['eventid' => $eventid,'firstname' => 'Ivan', 'lastname'=>'Bravo', 'email'=>'ivnbrv@mac.com');
如果事件上没有设置电子邮件,则它必须记录条目。
+-----------+----------+-----------+-----------+----------------+
| guestid | eventid | firstname | lastname | email |
+-----------+----------+-----------+-----------+----------------+
| 1 | 1 | Ivan | Bravo | ivnbrv@mac.com |
+-----------+----------+-----------+-----------+----------------+
我需要的是 eventid
作为主键和 guestid
作为 auto_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 |
+-----------+----------+-----------+-----------+----------------+
而且我还需要电子邮件作为唯一字段以防止重复行。
目前我正在使用 Laravel 5 Migrations,但是当我尝试重置主要字段时它会提示此错误:
Multiple primary key defined (SQL: alter table `event_guest` add primary key event_guest_eventid_guestid_primary(`eventid`, `guestid`))
这是我的迁移代码:
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'));
});
我真的需要帮助才能正确理解这一点。
我过去使用时没有遇到过问题:
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
现在
最佳答案
我明白你的要求。但我认为您在数据库中创建了太多冗余。您的情况保证了 Event 和 Guest 之间的 ManyToMany 关系。我相信,这将在很大程度上简化您的问题。因此,我提出的解决方案与您所要求的不同。
在您的问题中,Event
可以有多个 Guest
,而 Guest
可以属于多个 Event
。我们可以在 Laravel 5.* 中呈现它,如下所示,
事件
的迁移和模型
Schema::create('events', function(Blueprint $table){
$table->increments('id')->unsigned();
$table->string('title');
$table->string('venue');
$table->text('description');
$table->timestamps();
});
class Event extends Model{
public function guests(){
return $this->belongsToMany('App\Guest', 'event_guests');
}
}
Guest
的迁移和模型
Schema::create('guests', function(Blueprint $table){
$table->increments('id')->unsigned();
$table->string('email')->unique();
$table->string('password');
$table->string('first_name');
$table->string('last_name');
$table->timestamps();
});
class Guest extends Model{
public function events(){
return $this->belongsToMany('App\Event','event_guests');
}
}
event_guests
的迁移
Schema::create('event_guests', function(Blueprint $table){
$table->increments('id');
$table->integer('event_id')->unsigned();
$table->integer('guest_id')->unsigned()->nullable();
$table->foreign('guest_id')->references('id')->on('guests')->onDelete('cascade');
$table->foreign('event_id')->references('id')->on('events')->onDelete('cascade');
});
现在订阅 Guest
到 Event
就像下面一样简单
$event = Event::create([
'title' => 'Laracon',
'venue' => 'Hotel XYZ, New York',
'description' => 'Drink is not free'
]);
$guest = Guest::findOrFail($guestId);
$guest2 = Guest::findOrFail($guestId2);
$event->guests()->sync([$guestId->id, $guestId2->id], false); //`false` as second argument prevents `sync` from detaching previous associations
在这个策略中,您可以将event
和guest
数据分离到专用表中,而无需任何重复,并且可以非常轻松地维护唯一性约束。和你
创建数据透视表以维护他们的关系。
Read More关于 Laravel 关系。
关于php - Laravel 5 Schema Builder 中的唯一约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31197182/