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

As you say, the difference between the two is on which table the foreign key resides. The natural relationship would be

// Album model
function owner() {
  return $this->belongsTo('App\User', 'last_edit_by', 'user_id');
}

// User model
function albums() {
  return $this->hasMany('App\Album', 'last_edit_by', 'user_id');
}

hasOne is incorrect because "user_id" is not a foreign key, it is the primary key of the users table and "last_edit_by" is the foreign key. And although it works, it is an incorrect description of the relationship.

Hope it makes sense.

http://laravel.com/docs/4.2/eloquent#relationships

PS> By convention, user_id should be renamed "id" on the users table and "last_edit_by" should be renamed "user_id" on the albums table. But I don't want to confuse you further!

Last updated 9 years ago.
0

jacksoncharles said:

hasOne is incorrect because "user_id" is not a foreign key, it is the primary key of the users table and "last_edit_by" is the foreign key. And although it works, it is an incorrect description of the relationship.

Hope it makes sense.

I think it is beginning to make sense. I guess it leaves me wondering, why does it work? Is it wrong because 'by convention that's not how to do it"? Or is it wrong becase 'eventually this will NOT work, even though it does on this simple example'.

I'll make it right. I definitely don't want to leave it 'wrong' no matter the reason. But I'm trying to understand why its wrong. If I was unwise, and left it with the hasOne defined with the keys switched. Would it eventually break and not work as I built more complex queries? Or would it just become confusing keeping things straight, but if you did keep it straight, it would always work, even though technically wrong?

http://laravel.com/docs/4.2/eloquent#relationships

PS> By convention, user_id should be renamed "id" on the users table and "last_edit_by" should be renamed "user_id" on the albums table. But I don't want to confuse you further!

This is true, and I knew they weren't conventional names. But the database already exists. Is it worth the effort to rename all the database columns (there are many more than these two) to fall in line with convention? Or since the database exists as created by others, should I just leave it and deal with it as is.

I guess I don't know how important convention is in this matter.

Last updated 9 years ago.
0

I love this question as it brings up an interesting point about laravel. To me, laravel suffers from the same problem that php sometimes has, which is that it allows you to legally do something even though it is not recommended and sometimes ultimately not correct.

Both these relationships are legal but only one is correct in certain situations.

Imagine that you have two models, a User and a Company.

You can say "A user has one company" and conversely you can say "A user belongs to a company".

If you put the foreign key company_id in the users table then the natural relationship is that a user belongs to a company.

However it is legal in laravel to say

public function company()
{
return $this->hasOne('Company', 'id', 'company_id')
}

However, if you do that you will run into this problem

$user = User::find(1);
$company = Company::find(999);
$user->company()->associate($company); // <-- This method does not exist 

// the above method does not exist so you try to call save(), which is the correct method for hasOne
$user->company()->save($company); // <-- This method will execute but the result is not what you expect

// in the above save method it will execute this query
// update `companies` set `id` =  where `id` = 999
// yes that's right it made the company id an empty value
Last updated 9 years ago.
0

rickshawhobo said:

I love this question as it brings up an interesting point about laravel. To me, laravel suffers from the same problem that php sometimes has, which is that it allows you to legally do something even though it is not recommended and sometimes ultimately not correct.

Both these relationships are legal but only one is correct in certain situations.

Imagine that you have two models, a User and a Company.

You can say "A user has one company" and conversely you can say "A user belongs to a company".

If you put the foreign key company_id in the users table then the natural relationship is that a user belongs to a company.

However it is legal in laravel to say

public function company()
{
return $this->hasOne('Company', 'id', 'company_id')
}

However, if you do that you will run into this problem

$user = User::find(1);
$company = Company::find(999);
$user->company()->associate($company); // <-- This method does not exist 

// the above method does not exist so you try to call save(), which is the correct method for hasOne
$user->company()->save($company); // <-- This method will execute but the result is not what you expect

// in the above save method it will execute this query
// update `companies` set `id` =  where `id` = 999
// yes that's right it made the company id an empty value

Thanks rickshawhobo, that makes a bit more sense now. I think I'm seeing what the problem could eventually be. I think I actually did run into that type of problem earlier when I was defining the foreign_key field incorrectly, but I was leaving the 3rd argument blank. I was getting weird issues. And I think your explanation makes me understand why that wasn't working better.

Always better to do it 'right' even if 'not-right' isn't currently producing an error I guess.

0

Sign in to participate in this thread!

Eventy

Your banner here too?

Nertskull nertskull Joined 3 Apr 2015

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.