sterfry68
sterfry68

Reputation: 1093

Using Joins in Eloquent

I'm a relative beginner in Laravel 4 and I'm having trouble retrieving data from a joined table as defined in my model. I tried following the directions in Laravel's documentation here and here.

Here's what I did: I have a model (car.php) that successfully retrieves data from my cars table:

class Car extends Eloquent{
    public function parts(){
        return $this->hasMany('CarParts');
    }
}

Here's my CarParts model (car-parts.php):

class CarParts extends Eloquent{
    protected $table = 'car_parts';
    public function car(){
        return $this->hasOne('Car');
    }
}

I tried these to get to the data in the joined table:

echo Car::find(1)->parts;
// also tried:
$cars = Car::find(1)->get();
echo $cars->parts;

But I get this error message: Undefined property:Car::$parts

Upvotes: 1

Views: 423

Answers (4)

sterfry68
sterfry68

Reputation: 1093

Figured it out... I renamed my "CarParts" model to just "Parts". Also renamed the model file to "parts.php" and it worked. (Also fixed the relationship as edvinas.me noticed... but that didn't seem to matter to the result.) The camel-case thing is strange. Can anyone explain this to me? Here's what it looks like now:

class Car extends Eloquent{
    public function parts(){
        return $this->hasMany('Parts');
    }
}

class Parts extends Eloquent{
    protected $table = 'car_parts';
    public function car(){
        return $this->belongsTo('Car');
    }
}

Does eloquent just hate camel case?

Update:

I figured out why I was having this problem with the way I was naming my classes. As it turns out, one of my migration classes was already called CarParts. Simple problem, but I decided to post this update since I think it's pretty easy for someone else to make the same mistake.

Upvotes: 0

user1669496
user1669496

Reputation: 33118

The problem you are having is in your relationship. The inverse of hasMany() is belongsTo() so with that in mind, your models should looking something like this...

class Car extends Eloquent
{
    public function parts()
    {
        return $this->hasMany('CarParts');
    }
}


class CarParts extends Eloquent
{
    protected $table = 'car_parts';

    public function car()
    {
        return $this->belongsTo('Car');
    }
}

In order to find a car's parts, you can do something like this...

$parts = Car::find(1)->parts;
foreach($parts as $part) {
    echo $part->name;
}

You should also add the primaryKey properties to your models as well if they are not following the Laravel standards. Add this to CarPart with the appropriate key.

protected $primaryKey = 'car_part_id';

Upvotes: 1

ek9
ek9

Reputation: 3442

First, your relations should be defined like this:

<?php
class Car extends Eloquent {

    public function parts(){
        return $this->hasMany('CarPart');
    }
}

class CarPart extends Eloquent {
    protected $table = 'car_parts';
    public function car(){
        return $this->belongsTo('Car');
    }
}

You should do this:

Car::parts();

Or this:

$cars = Car::find(1);
$carParts = $cars->parts();

Upvotes: 0

Antonio Carlos Ribeiro
Antonio Carlos Ribeiro

Reputation: 87789

The best way is to use the dynamic property (->parts) so this should work for you:

$car = Car::find(1);

echo $car->parts;

or

$car = Car::find(1);

foreach($car->parts as $part)
{
    echo $part->name;
}

The parts() method gives you a query object, which may be used to filter a little more your parts:

$car = Car::find(1);

$parts = $car->parts()->where('model', '=', 'FORD')->get();

foreach($parts as $part)
{
    echo $part->name;
}

Also you probably will have to change your CarParts relation to:

$this->belongsTo('Car');

Upvotes: 1

Related Questions