Search code examples
phplaraveleloquentlaravel-5.5has-one

Laravel's relationship using Eloquent really correct?


I have a project running Laravel 5.5, and I have the following tables in the database.

USERS (
    ID,
    NAME,
    PERMISSION_ID
)

PERMISSIONS (
    ID,
    NAME
)

If I am not wrong, USERS relationship with PERMISSIONS is 1.1 (USERS has at least 1 permission and a maximum of 1), so it's a OneToOne relationship.

In my user model I made the following relationship.

class User extends Authenticatable
{
    public function permission () {
        return $this->hasOne('App\Models\Permission');
    }
}

But in this way Laravel/Eloquent looks for the relationship in the PERMISSIONS table. Generating a select similar to:

SELECT * FROM PERMISSIONS WHERE PERMISSIONS.USER_ID = 1

I have already consulted the Laravel documentation and saw that I can specify the ForeignKey and LocalKey in the hasOne method. This solves the relationship.

But is it really correct for Laravel/Eloquent by default to fetch the information in the PERMISSIONS table? The correct one would not be to look in the USERS table with PERMISSION_ID?

@Edit

Due to the response of Alexey Mezenin

I researched the difference between hasOne and belongsTo. And I found the following answer:

What is the difference between BelongsTo And HasOne in Laravel

From what I understood, when the foreign key is on the other table the correct one is to use hasOne.

When the foreign key is in the template's own table, the correct one is to use belongsTo.

I'll stay tuned in on these details next time, thanks Alexey Mezenin and jedrzej.kurylo


Solution

  • Your relationship is inverted, you're using hasOne() instead of belongsTo. Use this relationship in the User model:

    public function permission()
    {
        return $this->belongsTo(Permission::class);
    }
    

    And in the Permission model you might want to add hasOne() relationship (in case if you would want to use it):

    public function user()
    {
        return $this->hasOne(User::class);
    }
    

    But usually, the same permission can be used by many users. If this is the case, just change hasOne to hasMany.