简体   繁体   中英

Two relationships between two same models/tables

Problem

Hello, I'm having some trouble trying to make work two relationships between the two models (Laravel 5.5): Order and User .

1-----m | A User (as a customer) can make many Order s
1-----m | A User (as an employee) can take many Order s

So, in my orders table I have user_id and employee_id as foreign keys.

Now, some orders doesn't have an initial employee_id because orders need to be accepted, then I set up that value.

Using tinker, I've located this Order object (id:30), it has a user_id and a employee_id but when I dd() it, this returns:

=> App\Models\Order {#882
     order_id: 30,
     user_id: 7,  // <-- foreign key
     employee_id: 6,  // <-- foreign key
     restaurant_id: 4,  // <-- foreign key (for other table)
     // ...
     total: "120.00",
     created_at: "2018-01-31 00:15:41",
     updated_at: "2018-01-31 00:15:41",
     deleted_at: null,
     restaurant: App\Models\Restaurant {#900 // <- MY RESTAURANT RELATION (M-1)
       restaurant_id: 4,
       name: "Stark, Padberg and Buckridge",
       // ...
       // ...
       created_at: "2018-01-12 18:18:17",
       updated_at: "2018-01-12 18:18:17",
       deleted_at: null,
     },
     customer: App\Models\User {#914 // <- MY CUSTOMER RELATION (M-1)
       user_id: 7,
       restaurant_id: 4,
       // ...
       created_at: "2018-01-30 17:52:33",
       updated_at: "2018-01-30 23:32:00",
       deleted_at: null,
     },
     deliverer: null,  // <-- THIS SHOULD CONTAIN THE EMPLOYEE DATA
//                            THAT BELONGS TO THE DELIVERER RELATION
     }

What am I doing wrong?

-----

Information of my logic.

Models

Order

In my Order model I've defined the relationships (among other ones) as follows (all my primary keys follow this convention: model_id ):

/**
 * Return the user who created the order.
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 */
public function customer()
{
    return $this->belongsTo(
        'App\Models\User',
        'user_id',
        'user_id'
    );

}

/**
 * Return the employee (user) who deliver the order.
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 */
public function deliverer()
{
    return $this->belongsTo(
        'App\Models\User',
        'employee_id',
        'user_id'
    );
}

User

/**
 * A customer can make many orders
 * 
 * @return \Illuminate\Database\Eloquent\Relations\HasMany
 */
public function ordersMade()
{
    return $this->hasMany('App\Models\Order',
        'user_id',
        'user_id'
    );
}

/**
 * An employee attends many orders.
 *
 * @return \Illuminate\Database\Eloquent\Relations\HasMany
 */
public function ordersDelivered()
{
    return $this->hasMany('App\Models\Order',
        'employee_id',
        'user_id'
    );
}

Tables

This is the schema of my orders table:

订单表

This is the schema of my users table:

用户表


Update

Yes, I have users with ids 6 and 7 :

表

In Tinker i've done:

>>> $o = App\Models\Order::find(30);
>>> $o->customer;
>>> $o->restaurant;
>>> $o->deliverer;
>>> $o;

Well, there wasn't any problem with my code. I have the softDeletes set to true on my models, so I was trying to get a property of a "deleted" element.

As simple as that. Thanks to @MahdiYounesi, who made me check that.

although the problem was almost a stupid one, is a good remainder to note that when you need to also return softDeleted records when querying from an entity, you could just -as the docs says- add withTrashed() in each query that needs this kind of results, or directly in the model when defining the relationship like this:

/**
 * Return the user who created the order.
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 */
public function customer()
{
    return $this->belongsTo(
        'App\Models\User',
        'user_id'
    )->withTrashed();

}

/**
 * Return the employee (user) who deliver the order.
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 */
public function deliverer()
{
    return $this->belongsTo(
        'App\Models\User',
        'employee_id',
        'user_id'
    )->withTrashed();
}

This will collect the "deleted" data, usefull for historical information for example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM