Laravel中双外键关联同一表的实现及外键命名疑问
关于Laravel模型多关联同表的疑问解答
问题背景
我有一个Ticket模型,需要两次关联PriceTable表,分别对应SELL PRICE和REPAY PRICE(不同条目)。编写的模型关联代码如下:
Ticket模型
public function priceTableSell() { return $this->belongsTo('\App\PriceTable', 'pricetable_sell_id'); } public function priceTableRepay() { return $this->belongsTo('\App\PriceTable', 'pricetable_repay_id'); }
PriceTable模型
public function ticketsSell() { return $this->hasMany('\App\Ticket', 'pricetable_sell_id'); } public function ticketsRepay() { return $this->hasMany('\App\Ticket', 'pricetable_repay_id'); }
第一个外键通过如下迁移创建:
Schema::table('tickets', function (Blueprint $table) { $table->integer('pricetable_repay_id') ->unsigned() ->index() ->nullable(); $table->foreign('pricetable_repay_id') ->references('id') ->on('price_tables'); });
现在准备创建第二个外键时,发现数据库中已存在名为tickets_price_table_id_foreign的关联,有两个疑问:
- 是否需要先重命名现有关联再创建新的?或是有其他处理方式?
- 这种建立两个同表关联的方式是否正确?
解答
1. 外键关联名称的处理
不需要重命名现有的tickets_price_table_id_foreign关联。
Laravel会自动为新创建的外键生成唯一名称,比如针对pricetable_sell_id,默认生成的名称会是tickets_pricetable_sell_id_foreign,不会和现有名称冲突。如果担心自动生成的名称不符合预期,也可以手动指定外键名称,通过->name()方法:
Schema::table('tickets', function (Blueprint $table) { $table->integer('pricetable_sell_id') ->unsigned() ->index() ->nullable(); $table->foreign('pricetable_sell_id') ->references('id') ->on('price_tables') ->name('tickets_pricetable_sell_id_foreign'); });
只要保证每个外键的名称在数据库中唯一即可,无需修改已存在的关联。
2. 多关联同表的方式是否正确
这种建立两个同表关联的方式是完全正确的,符合Laravel的关联设计规范:
- 在
Ticket模型中通过两个belongsTo方法,分别指定不同的外键字段,区分两种关联关系; - 在
PriceTable模型中对应创建两个hasMany方法,同样指定对应的外键,实现反向关联。
后续可以正常通过以下方式调用关联:
- 获取票据的售价表:
$ticket->priceTableSell - 获取票据的还款价表:
$ticket->priceTableRepay - 获取某价格表关联的所有售票据:
$priceTable->ticketsSell - 获取某价格表关联的所有还款票据:
$priceTable->ticketsRepay
内容的提问来源于stack exchange,提问作者anderlaini
相关产品推荐
相关产品推荐

