0

I'm having trouble understanding how eager loading works with Lauravel/Eloquent. I'd like to grab all clients, do some stuff with them, and output their brand_name. I have these tables:

    Clients
+-------------------+
| Field             |
+-------------------+
| client_id         |
| client_name       |
| client_brand_id   |
+-------------------+

    Brands
+-------------------+
| Field             |
+-------------------+
| brand_id          |
| brand_name        |
+-------------------+  

In the client model I have the relationship:

public function brand()
{
    return $this->hasOne('Brand', 'client_brand_id', 'brand_id');
}

And inverse in the brands model:

public function clients()
{
    return $this->hasMany('Client', 'brand_id', 'client_brand_id');
}

I want to do this, but it doesn't work:

foreach( Client::with( 'brand' )->get( array('client_id', 'client_name' ) ) as $client ){
    echo $client->brand->brand_name;
}
Ryan Fisher
  • 1,485
  • 1
  • 19
  • 32

1 Answers1

1

You need to define your brand relationship in your client model like this:

public function brand()
{
    return $this->belongsTo('Brand', 'client_brand_id', 'brand_id');
}

The reason is that you have a one-to-many relationship, not a one-to-one relationship between clients and brands.

Also, you need to get the complete model for the eager loaded relationship to be available, like so:

foreach( Client::with( 'brand' )->get() as $client )
{
    echo $client->brand->brand_name;
}
lowerends
  • 5,469
  • 2
  • 24
  • 36
  • Perfect, thanks for adding the need for the complete model. I wasn't even thinking about that! – Ryan Fisher Aug 08 '14 at 08:29
  • You need all the keys (foreign and primary) relevant to the relationship, not necessarily complete models. – Jarek Tkaczyk Aug 08 '14 at 16:27
  • @JarekTkaczyk_deczo_ to do that, you are required to select the foreign/primary keys within the model specifically correct? Which limits that models use for other applications. Adding the keys to an array within the `get()` call does not work, the query that is built tries to select fields from the clients table without joining the brands table. – Ryan Fisher Aug 08 '14 at 20:58
  • 1
    @RyanFisher I don't get what you mean by within the model. Anyway, it's not going to `get` (using `get()`, which selects all the fields), since `with` calls another query. That being said, you need to use closure in the `with` call, and in that closure use `select`. – Jarek Tkaczyk Aug 10 '14 at 16:57