Laravel5.2-Eloquentテーブルのカスタム主キーとして文字列を使用すると0になります


84

テーブルの主キーとしてメールを使用しようとしているので、雄弁なコードは-

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class UserVerification extends Model
{
    protected $table = 'user_verification';
    protected $fillable =   [
                                'email',
                                'verification_token'
                            ];
    //$timestamps = false;
    protected $primaryKey = 'verification_token';
}

そして私のDBはこんな感じです-

ここに画像の説明を入力してください

しかし、私がこれを行う場合-

UserVerification::where('verification_token', $token)->first();

私はこれを手に入れています-

{
  "email": "sdfsdf@sdfsdf.sdf",
  "verification_token": 0,
  "created_at": "2016-01-03 22:27:44",
  "updated_at": "2016-01-03 22:27:44"
}

したがって、検証トークン/主キーは0になります。

誰か助けてもらえますか?

回答:


184

これは2015年12月29日にアップグレードのドキュメントに追加されたため、それ以前にアップグレードした場合は、おそらく見逃していたでしょう。

モデルから属性をフェッチするときに、その列を整数、文字列などとしてキャストする必要があるかどうかを確認します。

デフォルトでは、自動インクリメントテーブルの場合、このメソッドではIDは整数であると見なされます。

https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Eloquent/Model.php#L2790

したがって、解決策は次のとおりです。

class UserVerification extends Model
{
    protected $primaryKey = 'your_key_name'; // or null

    public $incrementing = false;

    // In Laravel 6.0+ make sure to also set $keyType
    protected $keyType = 'string';
}

3
$incrementingフィールドが保護されているのではなく公開されている理由はありますか?
Mubashar Abbas 2016

5
@MubasharAbbasモデルはEloquentと一致する必要があります。では、なぜEloquentは$incrementing公開して$primaryKey保護するのですか?それはかなり恣意的です。私は推測している$incrementing雄弁の以前のバージョンではゲッターやセッターメソッドを持っていなかった(今はない)と、彼らはただでそれらを追加した後に破壊変更を行うことを望まなかった
andrewtweber

1
主キー(またはEloquentでサポートされていない複合キー)がなく、そのようなテーブルをchunkで反復しようとすると、次のエラーが発生する可能性がありますSQLSTATE[42S22]: Column not found: 1054 Unknown column 'example.' in 'order clause'。この場合orderBy、Eloquentが主キーを使用してクエリに添付しようとしているステートメントを明示的に定義する必要があります。
antongorodezkiy 2017

これらがLaravelが行うタイプのことであり、私が心から愛することを妨げているのは悲しいことです。(他の多くの列で行うように)列タイプを検出する方が理にかなっていますか?
ミスアメリアサラ


7

設定する必要のあるモデルには2つのプロパティがあります。$primaryKey主キーを期待する列をモデルに最初に伝えます。2つ目$incrementingは、主キーが線形の自動インクリメント値ではないことを認識します。

class MyModel extends Model
{
    protected $primaryKey = 'my_column';

    public $incrementing = false;
}

詳細については、Eloquentに関するドキュメントPrimary Keysセクションを参照してください。


1
public $incrementing親クラスと一致する必要があります。
andrewtweber 2016年

2

私はPostmanを使用してLaravelAPIをテストしていました。

私は述べたエラーを受け取りました

「SQLSTATE [42S22]:列が見つかりません:1054不明な列」。Laravelが2つの列「created_at」と「updated_at」を自動的に作成しようとしたためです。

私はpublic $timestamps = false;自分のモデルに入らなければなりませんでした。次に、Postmanで再度テストし"id" = 0たところ、データベースに変数が作成されていることがわかりました。

私はついにpublic $incrementing false;APIを修正するために追加する必要がありました。


2

IDを使い続ける


<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class UserVerification extends Model
{
    protected $table = 'user_verification';
    protected $fillable =   [
                            'id',
                            'email',
                            'verification_token'
                            ];
    //$timestamps = false;
    protected $primaryKey = 'verification_token';
}

そしてメールを受け取る:

$usr = User::find($id);
$token = $usr->verification_token;
$email = UserVerification::find($token);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.