0

Alright, so here's my migrations...

public function up()
{
    Schema::create('instagrams', function (Blueprint $table) {
        $table->bigInteger('id')->unsigned()->primary();
        // ...
    });
}


public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->bigInteger('instagram_id')->unsigned()->nullable();
        // ...
    });
}

I have a user model, and an instagram model. Here's my instagram model:

class Instagram extends Model
{
    public function user()
    {
        return $this->hasOne('App\User');
    }
}

My problem is the instagram's relationship with the user isn't working. I can't access the user from an instagram, even when they're both in the database.

>>> $u = App\User::first()
=> App\User {#695
     id: 1,
     instagram_id: "3620243170",
   }
>>> $i = App\Instagram::first()
=> App\Instagram {#696
     id: "3620243170",
   }
>>> $i->user
=> null

So, I spent a long time wracking my brain until I found these helpful tinker methods... here's what it's giving me:

>>> $i->user()->toSql()
=> "select * from `users` where `users`.`instagram_id` = ? and `users`.`instagram_id` is not null"
>>> $i->user()->getBindings()
=> [
     2147483647,
   ]

Everything is in order except the ID is being maxed at the 32 bit limit by whatever code is hiding in laravel... the ID needs to be bigger than 32 bits because that's how instagram's IDs are stored. How can I get this relationship to work?

3
  • Store the Instagram ids as strings instead of big integers. Commented Jun 22, 2017 at 3:49
  • Does it work if you set the $keyType property on the Instagram model to 'float'? That is: protected $keyType = 'float'; Commented Jun 22, 2017 at 4:22
  • @sisve that would work but it feels like a workaround to an unnecessary problem... Commented Jun 22, 2017 at 5:14

1 Answer 1

5

It sounds like you're using a 32-bit version of PHP, where the max integer value is 2147483647.

The issue is that when the relationship query gets the key value of the Instagram instance to query the users, it automatically casts that id value to the type defined by the $keyType property on the model. This property is int by default.

So, even though your Instagram instance id is "3620243170", it is cast to an int, which in 32-bit PHP will turn it into 2147483647.

There are a couple things you can try to mitigate this issue:

  1. Use a 64-bit version of PHP. The max int size for 64-bit PHP matches the max int available for a signed bigint field. However, if you're using an unsigned bigint, you will run into this issue again once your ids exceed 9223372036854775807 (not likely).

  2. Change the $keyType property on your Instagram model to float, or possibly string. This only affects Eloquent's casting of the variables in PHP, it does not affect how they are stored in the database.
    Add protected $keyType = 'float'; to your Instagram model.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! I opted for changing the keyType as opposed to relying on a certain PHP environment since I may not always have control over that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.