Support the ongoing development of Laravel.io →
posted 10 years ago
Eloquent
Last updated 2 years ago.
0

This is because

public function creator() {
    return $this->belongsTo('User'); // Looks for creator_id
}

and

public function file() {
    return $this->hasOne('Asset'); // Looks for file_id
}
Last updated 2 years ago.
0

In your Asset.php try using

public function creator()
{
    return $this->belongsTo('User', 'user_id');
}

Where user_id is your foreign key. I'm thinking that by calling the function creator laravel will look for creator_id column as the foreign key.

Last updated 2 years ago.
0

eriktisme said:

This is because

public function creator() { return $this->belongsTo('User'); // Looks for creator_id }

True. That is my question. Why doesn't this work when the inverse works.

and

public function file() { return $this->hasOne('Asset'); // Looks for file_id }

This is false. It looks for user_id in the assets table. Basically for an hasOne dynamic property, the property name can be anything, but for a belongsTo property it has to be the same as the model name. Why?

Last updated 2 years ago.
0

iWader said:

In your Asset.php try using

public function creator()
{
   return $this->belongsTo('User', 'user_id');
}

Yes I know I can do that but that is not my question

Where user_id is your foreign key. I'm thinking that by calling the function creator laravel will look for creator_id column as the foreign key.

Last updated 2 years ago.
0

Well I guess it behaves that way because the function (and table column) is part of the model, rather than the related model.

I guess its one of those things thats personal preference as to how you like to setup your database schema.

Edit:

I see where you're coming from now. hasOne from the parent searches for the parent_id where as belongsTo looks for the function_id. Odd.

Last updated 2 years ago.
0

Let's have 3 models: 'Start', 'Middle' and 'End'. 'Start' has many 'Middle'-s, 'Middle' has many 'End'-s.
The foreign key of the Start-Middle relation is stored in the middles table.
The foreign key of the Middle-End relation is stored in the ends table. By defining the Middle model as

class Middle extends Eloquent ...
    public function start(){
        return $this->belongsTo('Start');
    }
    public function ends(){
        return $this->hasMany('End');
    }

Laravel will asume that the middles table contains a column called 'start_id', and that the ends table contains a column named 'middle_id'.
If you change the relationship names into

class Middle extends Eloquent ...
    public function previous(){
        return $this->belongsTo('Start');
    }
    public function next(){
        return $this->hasMany('End');
    }

Laravel will assume that there is a 'previous_id' in the middles table, and still a 'middle_id' column in the ends table. It always assumes a 'model_name_id' column in the other table in case of a hasMany relationship.
If this answers your question, mark it as solved.

Last updated 2 years ago.
0

I appreciated the thorough response but it still hasn't answered my question of "why". In this code

public function previous(){
    return $this->belongsTo('Start');
}

I see no reason why laravel can't assume the middles table has start_id instead of previous_id. I think it should assume the foreign key should be the snake case of the related object that was given. In this case it should be start_id

I found this in the source code

// If no relation name was given, we will use this debug backtrace to extract
// the calling method's name and use that as the relationship name as most
// of the time this will be what we desire to use for the relationships.

I just find this behavior inconsistent with the way hasOne() works

Last updated 2 years ago.
0

The following code in Eloquent\Model.php

if (is_null($foreignKey))
{
    $foreignKey = snake_case($relation).'_id';
}

$instance = new $related;

can be refactored to

$instance = new $related;
$foreignKey = $foreignKey ?: $instance->getForeignKey();

and still maintain backward compatibility assuming most people use the same class name as the function name (which they would have had to if $foreignKey was empty)

Last updated 2 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.