Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Eloquent model id as string return wrong value in

There is OauthClient model which $client->id does not return correct value in Laravel 5.2.

"lucadegasperi/oauth2-server-laravel": "^5.1" is used that has in migration $table->string('id', 40)->primary();

However when use $client->id in blade template then I get back "0" . Using dd($client) show correct value in id attribute.

What could be wrong?

Model output from dd()

OauthClient {#254 ▼
  #connection: null
  #table: null
  #primaryKey: "id"
  #keyType: "int"
  #perPage: 15
  +incrementing: true
  +timestamps: true
  #attributes: array:7 [▼
    "id" => "wISw4JmlMQCCrMupjojcuDTK3k4hwtkb"
    "secret" => "nnw3CPTzeQSIfT4KpR0d3XzWIKKoghB3"
    "name" => "http://example.com"
    "package" => "free"
    "user_id" => 2
    "created_at" => "2016-07-19 15:36:28"
    "updated_at" => "2016-07-19 15:36:28"
  ]
  #original: array:7 [▶]
  #relations: []
  #hidden: []
  #visible: []
  #appends: []
  #fillable: []
  #guarded: array:1 [▼
    0 => "*"
  ]
  #dates: []
  #dateFormat: null
  #casts: []
  #touches: []
  #observables: []
  #with: []
  #morphClass: null
  +exists: true
  +wasRecentlyCreated: false
}

Table structure from "show create table oauth_clients"

CREATE TABLE `oauth_clients` (
  `id` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
  `secret` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `package` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `oauth_clients_id_secret_unique` (`id`,`secret`),
  KEY `oauth_clients_user_id_foreign` (`user_id`),
  CONSTRAINT `oauth_clients_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
like image 690
Margus Pala Avatar asked Jul 19 '16 16:07

Margus Pala


2 Answers

This is because by default the primary key is casted as int unless explicitly stated otherwise.

(int) "wISw4JmlMQCCrMupjojcuDTK3k4hwtkb" == 0

The value still exists as string, but if you use the $model->id it will go through magic __get() method defined in Illuminate\Database\Eloquent\Model class.

I'm not going to argue against using id field as string, but if you do and also want to get the string value using $model->id, you'll have to cast it as string in you model definition. There is a protected $casts array you can use for that. Just add the following to your OauthClient model:

protected $casts = ['id' => 'string'];

This will do the trick and cast the id attribute as string instead of default integer. All though I would reccommend not to use id as string in the first place.

Update:

There is also an $incrementing property, which you can set to false on your models, to tell Laravel you want non-incrementing or non-numeric primary key. Set it on your models like this:

public $incrementing = false;

Update 2:

Information about this is now also added to official documentation. Look for Primary Keys section at Eloquent docs:

In addition, Eloquent assumes that the primary key is an incrementing integer value, which means that by default the primary key will be cast to an int automatically. If you wish to use a non-incrementing or a non-numeric primary key you must set the public $incrementing property on your model to false. If your primary key is not an integer, you should set the protected $keyType property on your model to string.

like image 135
ruuter Avatar answered Nov 17 '22 21:11

ruuter


Setting public $incrementing = false; worked for me.

http://www.laravel.io/forum/12-14-2015-id-as-string

like image 30
act28 Avatar answered Nov 17 '22 22:11

act28