php - Laravel 5 Schema Builder 中的唯一约束

标签 php laravel orm laravel-5 eloquent

首先,我想告诉你,我在网上搜索了这个问题,也没有能够解决这个问题。

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

我有 2 个表,eventsevent_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');
});

现在订阅 GuestEvent 就像下面一样简单

$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

在这个策略中,您可以将eventguest 数据分离到专用表中,而无需任何重复,并且可以非常轻松地维护唯一性约束。和你 创建数据透视表以维护他们的关系。

Read More关于 Laravel 关系。

关于php - Laravel 5 Schema Builder 中的唯一约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31197182/

相关文章:

php - 如何组织所有js、css、php和html代码?

php - Laravel "partial"播种

php - 是否可以将自定义字段添加到 Drupal 分类术语中?

php - Laravel 5.7 作业队列未异步运行

php - 在命令行上运行 Artisan (Laravel) 时出现 fatal error

php - 为什么在 PHP 中使用 ORM?

c# - 如何编写自己的基于XmlService 的ORM?

database - europass 数据库结构关系或 noSql

Php exec 函数没有按预期工作

php - 我们如何监控 SOLR 数据获取速度?