Laravel 5.6 OneToOne关系不起作用

时间:2018-11-15 15:15:48

标签: php laravel eloquent relationship

我有一个BuildingImage模型,该模型与BuildingType具有OneToOne关系:

BuildImage模型:

/**
 * Get the source type of the Building Image.
 */
public function type()
{
    return $this->hasOne('App\BuildingType');
}

BuildingType模型:

/**
 * Get the Building Image that owns the building type.
 */
public function buildingImage()
{
    return $this->belongsTo('App\BuildingImage');
}

我的桌子:

building_images表->源是建筑物类型ID

source is the building type id

building_types表

enter image description here

当我尝试在控制器中执行此操作只是为了进行测试时: (一个ImageRequest具有一个或多个建筑物,而建筑物具有一个BuildingType)

$imageRequest = ImageRequest::findOrFail($id);

$buildings = $imageRequest->buildingImages;

foreach ($buildings as $building) {
    dd($building->type);
}

我收到此错误:

  

SQLSTATE [42S22]:找不到列:1054未知列   “ where子句”中的“ building_types.building_image_id”(SQL:选择*   来自building_types,其中building_typesbuilding_image_id = 45   和building_typesbuilding_image_id不能为空限制1)

我在这里做什么错了?

3 个答案:

答案 0 :(得分:3)

这是因为默认情况下,laravel将查找名为{model}_id的主键,并且鉴于您使用的是不同的列名(source),因此在定义关系时需要指定: >

作为文档states

  

Eloquent根据模型名称确定关系的外键。在这种情况下,将自动假定Phone模型具有一个user_id外键。如果您希望重写此约定,则可以将第二个参数传递给hasOne方法:

return $this->hasOne('App\Phone', 'foreign_key');
     

此外,Eloquent假定外键的值应与父级的id(或自定义$primaryKey)列匹配。换句话说,Eloquent将在user_id记录的Phone列中查找用户id列的值。如果您希望该关系使用id以外的值,则可以将第三个参数传递给hasOne方法,以指定您的自定义键:

return $this->hasOne('App\Phone', 'foreign_key', 'local_key');

现在,这很清楚。让我们谈谈关系本身。

您正在定义BuildImage有一个BuildingType。但是使用这种逻辑,外键应该存储在building_types表中,而不是相反(source列出现在building_images表中)。而且-我只是假设-许多BuildImage可以属于一个特定的BuildingType。因此,如果这个假设是正确的:

  • BuildImage属于特定的BuildingType
  • 可以在许多BuildinType中指定一个BuildImage

因此,您应该这样定义您的关系:

BuildImage.php

public function type()
{
    return $this->belongsTo('App\BuildingType', 'source');
}

BuildingType.php

public function images()
{
    return $this->hasMany(BuildingImage::class, 'source');
}

答案 1 :(得分:1)

您的BuildImage模型应为

/ **  *获取建筑物图像的源类型。  * /

public function type() {
    return $this->hasOne('App\BuildingType',"id","source"); 
}

并且BuildingType模型应该为

/ **  *获取拥有建筑物类型的建筑物图像。  * /

public function buildingImage()
{
    return $this->belongsTo('App\BuildingImage',"source","id");
}

这应该有效。 欲了解更多信息,请看 https://laravel.com/docs/5.7/eloquent-relationships#one-to-one

答案 2 :(得分:0)

您是否尝试过这样指示索引ID?

public function buildingImage()
{
    return $this->belongsTo('App\BuildingImage', 'image_request_id');
}
  

Eloquent根据以下内容确定关系的外键   型号名称。在这种情况下,电话型号会自动假定为   有一个user_id外键。如果您想覆盖此约定,   您可以将第二个参数传递给hasOne方法:

return $this->hasOne('App\Phone', 'foreign_key');

https://laravel.com/docs/5.7/eloquent-relationships#one-to-one