迟到评论
此方法的唯一方法似乎是以 table_name_primary_key 格式定义外键列。如果它们不适合这种格式,那么在没有指定列名的情况下关系就不起作用。
我正在尝试学习如何使用reliese/laravel
代码生成器(它从数据库生成模型)使用外键,但是我有一个问题迫使我重新指定所有的外键名称生成的代码。这是我的迁移代码和生成的关系代码:
//迁移
Schema::create('hotels', function(Blueprint $table) {
$table->increments('hotel_id');
$table->string('name', 64);
$table->string('description', 512);
$table->softDeletes();
$table->timestamps();
});
Schema::create('floors', function(Blueprint $table){
$table->increments('floor_id');
$table->integer('hotel_id')->unsigned();
$table->string('label', 128);
$table->softDeletes();
$table->timestamps();
$table->foreign('hotel_id')->references('hotel_id')->on('hotels')->onDelete('cascade');
});
//关系
// Hotel.php contains
public function floors()
{
return $this->hasMany(\Otellier\Floor::class);
}
// Floor.php contains
public function hotel()
{
return $this->belongsTo(\Otellier\Hotel::class);
}
现在,当我用Faker创建一个地板时:
$hotel = factory(App\Hotel::class)->make();
$floor = factory(App\Floor::class)->make([ "label" => "Floor #" . $floor_number ]);
$hotel->floors()->save($floor);
在最后一行中,我收到此错误:
Illuminate \ Database \ QueryException:SQLSTATE [42S22]:找不到列:1054'字段列表'中的未知列'hotel_hotel_id'(SQL:插入
floors
label
,{{1} },hotel_hotel_id
,updated_at
)值(楼层#1,8,2018-03-22 12:37:39,2018-03-22 12:37:39))
显然,它会搜索created_at
字段作为hotel_hotel_id
表中的列,我怀疑它是将表名添加为列名的前缀。为什么会发生这种情况,如何防止这种情况并强制整个系统不要在任何列前加上
floors
答案 0 :(得分:1)
Laravel使用 Model.php 中的getForiegnKey()
方法来预测关系的foriegnkey。
/**
* Get the default foreign key name for the model.
*
* @return string
*/
public function getForeignKey()
{
return Str::snake(class_basename($this)).'_'.$this->primaryKey;
}
您可以在模型中覆盖或基类来更改其行为。在你的情况下,它可以像,
一样使用public function getForeignKey()
{
return $this->primaryKey;
}
当关系尝试Io访问通讯员foriegnkey时,它将返回您的$primaryKey
作为foriegn键。
注意:如果您指定关系中的foriegn键,则此方法无法正常工作。
答案 1 :(得分:0)
您需要在模型中定义自己的主键:
protected $primaryKey='floor_id';
和另一个:
protected $primaryKey='hotel_id';
答案 2 :(得分:0)
执行此操作而不修改生成的文件或核心需要以 table_name_primary_key 格式定义外键列。如果他们不适合这种格式,那么在没有指定列名的情况下关系就不起作用。
答案 3 :(得分:0)
默认情况下,eloquent根据模型名称确定关系的外键。在这种情况下,自动假定Floor
模型具有hotel_id
外键。此外,Eloquent假定外键应具有与父级的id(或自定义$primaryKey
)列匹配的值。换句话说,Eloquent会在id
的{{1}}列中查找酒店hotel_id
列的值。如果您希望关系使用{{1}以外的值您可以将第三个参数传递给指定自定义Floor
id