Laravel model :: create () не возвращает первичный ключ - PullRequest
1 голос
/ 21 июня 2020

У меня есть следующая таблица авторизации:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class CreateAuthTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('auth', function (Blueprint $table) {
            $table->uuid('id')->primary();
            $table->string('email', 255)->index()->unique();
            $table->string('password', 96);
            $table->timestamps();
        });
        DB::statement('ALTER TABLE auth ALTER COLUMN id SET DEFAULT uuid_generate_v4();');
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('auth');
    }
}

А это модель:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticable;
use Illuminate\Support\Facades\Hash;
use Laravel\Passport\HasApiTokens;

class User extends Authenticable
{
    use HasApiTokens;

    protected $table = "auth";
    protected $fillable = ["email", "password"];
    public $incrementing = false;
    protected $keyType = 'string';
    protected $casts = [
        'id' => 'string'
    ];

    private $hashOptions = [
        'memory' => 1024,
        'time' => 2,
        'threads' => 1
    ];

    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = Hash::make($value, $this->hashOptions);
    }
}

А в UserController я создаю таких пользователей:

<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class UserController extends Controller
{
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "email" => "required|email|unique:auth",
            "password" => "required|string|min:2|max:255",
            "password_confirm" => "required|same:password"
        ]);


        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        $credentials = $request->only('email', 'password');

        $exists = User::where('email', $credentials['email'])->first();
        if ($exists) {
            return response()->json([
                "error" => "Email already exists"
            ], 409);
        }

        $user = User::create($credentials);

        dd($user->id); // This is always null

        return response()->json([
            'data' => [
                "id" => $user->id,
                "email" => $request->email,
            ]
        ]);
    }
}

Однако ответ $user->id всегда равен нулю. Разве Model::create не должен возвращать идентификатор вновь созданной записи?

Я также пробовал кучу таких комбинаций:

// Models\User.php

public $incrementing = false;
protected $keyType = 'string';
protected $casts = [
    'id' => 'string'
];

Но результат всегда один и тот же. Я использую Laravel 7 с Postgres SQL 12,3.

1 Ответ

2 голосов
/ 21 июня 2020

Просто убедитесь, что приведение приведено как строка и имя первичного ключа правильное

namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
  protected $casts = [
    'id' => 'string'
  ];
  protected $primaryKey = "id";
}

если вы установите $ incrementing на false, он сломает его и всегда вернет false, поскольку он сообщает код что идентификатор не создается автоматически, поэтому никогда не извлекается.

class User extends Model
{
  public $incrementing = false;
  // ...
}

$user = new User;
$user->save();
dd($user->id);
// null

Также не забудьте включить расширение uuid при миграции

<?php

class AddUuidExtensionToPostgre extends Migration
{

    public function up()
    {
        DB::statement('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";');
    }

    public function down()
    {
        DB::statement('DROP EXTENSION IF EXISTS "uuid-ossp";');
    }
}

вот пример


Schema::create('users', function (Blueprint $table) {
    $table->uuid('id');
    $table->primary('id');
    // ...
});

DB::statement('ALTER TABLE users ALTER COLUMN id SET DEFAULT uuid_generate_v4();');

...