Reputation: 576
I have a BuildingImage model with a OneToOne relation to BuildingType:
BuildImage Model:
/**
* Get the source type of the Building Image.
*/
public function type()
{
return $this->hasOne('App\BuildingType');
}
BuildingType Model:
/**
* Get the Building Image that owns the building type.
*/
public function buildingImage()
{
return $this->belongsTo('App\BuildingImage');
}
My tables:
building_images table -> source is the building type id
building_types table
When I try to do this in my controller just to test: (an ImageRequest has one or more Builings and a Building has one BuildingType)
$imageRequest = ImageRequest::findOrFail($id);
$buildings = $imageRequest->buildingImages;
foreach ($buildings as $building) {
dd($building->type);
}
I get this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'building_types.building_image_id' in 'where clause' (SQL: select * from
building_types
wherebuilding_types
.building_image_id
= 45 andbuilding_types
.building_image_id
is not null limit 1)
What am I doing wrong here?
Upvotes: 1
Views: 496
Reputation: 14251
That's because by default laravel will look for a primary key named {model}_id
, and given that you are using a different column name (source
), you need to specify when defining the relationship:
As the documentation states:
Eloquent determines the foreign key of the relationship based on the model name. In this case, the
Phone
model is automatically assumed to have auser_id
foreign key. If you wish to override this convention, you may pass a second argument to thehasOne
method:return $this->hasOne('App\Phone', 'foreign_key');
Additionally, Eloquent assumes that the foreign key should have a value matching the
id
(or the custom$primaryKey
) column of the parent. In other words, Eloquent will look for the value of the user's id column in theuser_id
column of thePhone
record. If you would like the relationship to use a value other than id, you may pass a third argument to thehasOne
method specifying your custom key:return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
Now that that is clear. Let's talk about the relationship itself.
You are defining that a BuildImage
has one BuildingType
. But with that logic, the foreign key should be stored in the building_types
table, and not the other way around (source
column appears in the building_images
table). And -I'm just assuming that- many BuildImage
can belongs to an specific BuildingType
. So, if this assumption is correct:
BuildImage
belongs to a specific BuildingType
.BuildinType
can be specify in many BuildImage
sSo, you should define your relationship like this:
BuildImage.php
public function type()
{
return $this->belongsTo('App\BuildingType', 'source');
}
BuildingType.php
public function images()
{
return $this->hasMany(BuildingImage::class, 'source');
}
Upvotes: 3
Reputation: 1938
Your BuildImage model should be
/** * Get the source type of the Building Image. */
public function type() {
return $this->hasOne('App\BuildingType',"id","source");
}
And BuildingType Model should be
/** * Get the Building Image that owns the building type. */
public function buildingImage()
{
return $this->belongsTo('App\BuildingImage',"source","id");
}
This should work. For more info have a look https://laravel.com/docs/5.7/eloquent-relationships#one-to-one
Upvotes: 1
Reputation: 269
Have you tried to indicate the index ID like this?
public function buildingImage()
{
return $this->belongsTo('App\BuildingImage', 'image_request_id');
}
Eloquent determines the foreign key of the relationship based on the model name. In this case, the Phone model is automatically assumed to have a user_id foreign key. If you wish to override this convention, you may pass the second argument to the hasOne method:
return $this->hasOne('App\Phone', 'foreign_key');
https://laravel.com/docs/5.7/eloquent-relationships#one-to-one
Upvotes: 0