Laravel雄辩的关系表前缀

时间:2018-03-22 12:59:20

标签: laravel eloquent foreign-keys laravel-5.6

  

迟到评论

     

此方法的唯一方法似乎是以 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_idupdated_at)值(楼层#1,8,2018-03-22 12:37:39,2018-03-22 12:37:39))

显然,它会搜索created_at字段作为hotel_hotel_id表中的列,我怀疑它是将表名添加为列名的前缀。为什么会发生这种情况,如何防止这种情况并强制整个系统不要在任何列前加上

没有这样做:

floors

4 个答案:

答案 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

的hasMany方法
id