Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

RadicalActivity's avatar

Confused with Laravel's hasOne Eloquent Relationships

I have a new Laravel 5.8 application. I started playing with the Eloquent ORM and its relationships.

There is a problem right away that I encountered.

I have the following tables. (this is just an example, for testing reasons, not going to be an actual application)

Login table:
--------------------------
| id | user    | data_id |
--------------------------
| 1  | admin   | 1       |
| 2  | admin   | 2       |
| 3  | admin   | 3       |
--------------------------

Data table:
--------------
| id | ip_id |
--------------
| 1  | 1     |
| 2  | 2     |
| 3  | 3     |
--------------

IP table:
----------------------
| id | ip            |
----------------------
| 1  | 192.168.1.1   |
| 2  | 192.168.1.2   |
| 3  | 192.168.1.3   |
----------------------

What I wanted is to get the IP belonging to the actual login.

So I added a hasOne relationship to the Login table that has a foreign key for the Data table:

public function data()
{
    return $this->hasOne('App\Models\Data');
}

Then I added a hasOne relationship to the Data table that has a foreign key for the IP table:

public function ip()
{
    return $this->hasOne('App\Models\Ip');
}

Once I was done, I wanted to retrieve the IP address for the first record of the Login table:

Login::find(1)->data()->ip()->get();

But I get this error:

Call to undefined method Illuminate\Database\Eloquent\Relations\HasOne::ip()

What am I missing here and how can I get the IP of that login in the correct way? Do I need a belongsTo somewhere?

0 likes
2 replies
mstrauss's avatar
mstrauss
Best Answer
Level 14

Try this:

Data::find(Login::find(1)->data_id)->ip

That should work, but it looks confusing, right? That's because the relationships aren't quite right, try this:

Ip Model

public function data()
{
    return $this->belongTo('App\Models\Data');
}

Data Model

public function ip()
{
    return $this->hasOne('App\Models\Ip');
}

public function login()
{
    return $this->belongsTo('App\Models\Login');
}

Login Model

public function ip()
{
    return $this->hasOne('App\Models\Data');
}

Then you should be able to do something like:

Login::find(1)->data->ip; 

Or you can take it a step further and try this:

Login Model

    public function ipData()
    {
        return $this->hasOneThrough('App\Ip', 'App\Data');
    }

Then, you should be able to do something like:

Login::find(1)->ipData; 

Please or to participate in this conversation.