Search code examples
laraveleloquentuuidrelation

Laravel relation "sometimes" returns null


I have a strange problem with a Laravel relation.

  • Laravel version: 7.27.0
  • Usage of BinaryCabin\LaravelUUID for some models.

The whole app runs smoothly and I have a fair understanding on relationships in Laravel, but recently I started to investigate some app data for statistical reasons and ran into the following problem.

I have check-in events in a table:

-----------------------------------------------------------------------------------------------------------------------
|  id  | user_id                              | booking_id                           | check_in            | check_out|
-----------------------------------------------------------------------------------------------------------------------
| 1257 | b9189540-bf96-11ea-bfb2-fb5284940ca4 | bc7d2500-c779-11ea-9d49-c7bb70e58097 | 2020-07-22 10:14:18 | null     |
| 1541 | b9189540-bf96-11ea-bfb2-fb5284940ca4 | 2e8749e0-ccd5-11ea-9b46-9febde327734 | 2020-07-23 13:12:31 | null     |
-----------------------------------------------------------------------------------------------------------------------

The accompanying bookings table is set up with the foreign keys and the records exist.

Schema::create('bookings', function (Blueprint $table) {
    $table->engine = 'InnoDB';
    $table->uuid('id')->primary();
    $table->uuid('user_id');
    ...
});
Schema::create('checkins', function (Blueprint $table) {
    $table->id();
    $table->uuid('user_id');
    $table->uuid('booking_id');
    $table->foreign('booking_id')->references('id')->on('bookings')->onUpdate(null)->onDelete(null);
    ...
});

I also have the relations in place:

// Booking.php

class Booking extends Model
{
    use SoftDeletes, HasUUID;

    protected $table            = 'bookings';
    protected $uuidFieldName    = 'id';

    public function checkIn()
    {
        return $this->hasOne(CheckIn::class);
    }

    ...
// CheckIn.php

class CheckIn extends Model
{
    protected $table = 'checkins';
    
    public function booking()
    {
        return $this->belongsTo(Booking::class, 'booking_id', 'id');
    }

    ...

I now run an eloquent query with:

$user = User::where('id', 'b9189540-bf96-11ea-bfb2-fb5284940ca4')->first();
if ($user) 
{
    $bookings = $user->bookings()->with('checkIn', 'resource', 'resource.location')
                                 ->withTrashed()
                                 ->orderBy('date', 'asc')
                                 ->get();
}

The weird result is that I only get the relation data for the first record but not for the second one (abbreviated for readability):

id: "bc7d2500-c779-11ea-9d49-c7bb70e58097"
check_in: {id: 1257, user_id: "b9189540-bf96-11ea-bfb2-fb5284940ca4", booking_id: "bc7d2500-c779-11ea-9d49-c7bb70e58097", check_in: "2020-07-22 10:14:18", check_out: null, created_at: "2020-07-22T08:14:18.000000Z", id: 1257, updated_at: "2020-07-22T08:14:18.000000Z", user_id: "b9189540-bf96-11ea-bfb2-fb5284940ca4"}
resource: {id: 4, name: "XXX", ...} 
user_id: "b9189540-bf96-11ea-bfb2-fb5284940ca4"

id: "2e8749e0-ccd5-11ea-9b46-9febde327734"
check_in: null
resource: {id: 4, name: "XXX", ...} 
user_id: "b9189540-bf96-11ea-bfb2-fb5284940ca4"

After some time I finally checked Telescope for the submitted relation query and got this:

select
  *
from
  `checkins`
where
  `checkins`.`booking_id` in (
    1,
    0,
    0,
    0,
    115,
    1661,
    19,
    1,
    1,
    100000,
    1,
    203,
    20,
    20,
    238,
    23,
    23,
    242,
    275,
    28820,
    29,
    2,
    0,
    2,
    2,
    385065,
    38,
    3980,
    3,
    43539880,
    56,
    5,
    5,
    5,
    5,
    64078300,
    6831,
    74575330,
    77,
    7,
    83,
    864465,
    8,
    8,
    9223372036854775807,
    900,
    918,
    92,
    95,
    961852,
    990,
    99,
    9,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0
  )

What are these ids? I really don't know what to do with this. Is this a problem with the UUID lib I am using? But then, why does the first relation work? Any hint is highly appreciated. Thanks in advance.


Solution

  • If you're using https://github.com/binarycabin/laravel-uuid then you need to use the trait UUIDIsPrimaryKey for all tables with a uuid as a primary key i.e.

    class Booking extends Model
    {
        use SoftDeletes, HasUUID, UUIDIsPrimaryKey;
    

    This is likely linked to the $keyType attribute mentioned in Eloquent model conventions