Search code examples
phpmysqleloquentlaravel-5.3

Laravel : relations are not working in every ways of the request


Given two tables :

Package
--------
int id
int parcel_id
int order_id
timestamps()

Order
--------
int id
int user_id
int search_id
timestamp shipping_date
timestamps()

There are one or many Package objects which belongs to an Order,

Respectively, one Order object has one or many Package objects.

Package Model :

public function order() {
    return $this->belongsTo('App\Order');
}
public function parcel() {
    return $this->belongsTo('App\Parcel');
}

Order Model :

public function search() {
    $this->belongsTo('App\Search');
}
public function user() {
    $this->belongsTo('App\User');
}
public function packages() {
    $this->hasMany('App\Package');
}

Question :

I succeed to get the Order of the Package but I can't get the Packages associated with an Order. Why is that ?

I do have the same behaviour the other way around, this time from User, finding the belonging Search.

Search works correctly when I try to find the Search->user.

I have the exact same Model structure with User has_many Adresses, and Address belongs to User, which works well in both ways.

My guess is that it's because there are many keys involved into both tables, but I still give the column name into the belongTo/hasMany attribute and if I recall correctly, Eloquent relations are based on column and table names, not on the "real" MySQL relations (foreign keys, etc).

Illustration in php artisan tinker :

>>> $package = App\Package::where('id', 224)->first()
=> App\Package {#800
     id: 224,
     parcel_id: 2,
     weight: 10,
     created_at: "2016-12-29 14:00:58",
     updated_at: "2016-12-29 14:00:58",
     order_id: 115,
   }
>>> $package->order
=> App\Order {#743
     id: 115,
     user_id: 1,
     search_id: 1,
     created_at: "2016-12-29 14:00:58",
     updated_at: "2016-12-29 14:00:58",
     shipping_date: "2016-12-29 14:00:58",
   }
>>> $order = App\Order::where('id', 115)->first()
=> App\Order {#804
     id: 115,
     user_id: 1,
     search_id: 1,
     created_at: "2016-12-29 14:00:58",
     updated_at: "2016-12-29 14:00:58",
     shipping_date: "2016-12-29 14:00:58",
   }
>>> $order->packages
LogicException with message 'Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation'
>>> $order->packages()
=> null

Solution

  • You're missing a return statement on your Order model.

    public function search() {
        return $this->belongsTo('App\Search');
    }
    public function user() {
        return $this->belongsTo('App\User');
    }
    public function packages() {
        return $this->hasMany('App\Package');
    }
    

    You were returning void which is not a laravel relationship. ;)