Laravel schema builder primary key as foreign key

只谈情不闲聊 提交于 2019-12-07 18:46:25

问题


I'm using the Laravel 4.2 schema builder to create some tables referencing each other, and am having some issues.

I have a simplified ERD. Note that only relevant columns are shown:

Note that I cannot modify the tblcurrencies and tbldomains tables in any way, since I am developing a module to hook into an existing system.

I am trying to achieve the following:

  1. The extensions table contains extra information about rows in the tbldomains table
  2. The prices table contains pricing information about a domain in a certain currency, with the additional type value (registration, renewal, transfer)
  3. I want to use foreign keys so that I can cascade deletions.

Currently, I use the following code to create the two tables:

Capsule::schema()->create('extensions', function ($table) {
    $table->engine = 'InnoDB';
    $table->integer('relid', 10);
    // ...
    $table->primary(['relid']);
    $table->foreign('relid')->references('id')->on('tbldomains')->onDelete('cascade');
});

Capsule::schema()->create('prices', function ($table) {
    $table->engine = 'InnoDB';
    $table->integer('relid', 10);
    $table->integer('currency', 10);
    $table->enum('type', ['domainregister', 'domainrenew', 'domaintransfer']);
    // ...
    $table->primary(['relid', 'currency', 'type']);
    $table->foreign('relid')->references('relid')->on('extensions')->onDelete('cascade');
    $table->foreign('currency')->references('id')->on('tblcurrencies')->onDelete('cascade');
});

The creation script for the prices table results in the following SQL query:

create table `prices` (`relid` int unsigned null auto_increment primary key, `currency` int unsigned null auto_increment primary key, `type` enum('domainregister', 'domainrenew', 'domaintransfer') not null, ...) engine = InnoDB

Which in turn results in the following error:

SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key

I have also tried setting the primary keys as unique instead, figuring that perhaps Laravel automatically set primary integer keys as auto increment.

Furthermore, I tried setting the columns as unsigned and index, as suggested by this and this answer

How do I stop the schema builder from setting the relid and currency fields to auto increment, since they are simply foreign keys?


回答1:


based on Laravel Documentation Api on the below link, only string() method can have length attribute. Laravel Documentation Api

So to make those two column unsigned and not primary key or auto increment make the following change:

from this:

$table->integer('relid', 10);
$table->integer('currency', 10);

to this:

$table->integer('relid', false, true);
$table->integer('currency', false, true);

Because as per the documentation the integer() method syntax is:

integer(string $column, bool $autoIncrement = false, bool $unsigned = false)

And what you did is you assigned a value (10) to a boolean variable ($autoIncrement) which will always returns true on this case. For further proof of this, please refer back to the below link from php.net. php.net Boolean

I had the same issue before, and when I start referring back Laravel documentation 90% of confusion will be cleared. Hope this helps you.


Note: you can also use unsignedInteger() method, which i think it's more explicit and easier to remember:

unsignedInteger(string $column, bool $autoIncrement = false)

So the code will be like so:

$table->unsignedInteger('relid');
$table->unsignedInteger('currency');


来源:https://stackoverflow.com/questions/41504219/laravel-schema-builder-primary-key-as-foreign-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!