Home > OS >  How To Set ForeignKey As PrimaryKey Using UUID Trait
How To Set ForeignKey As PrimaryKey Using UUID Trait

Time:09-03

I have 2 table that separate users' login info (email, username, password) and general info (full_name, address, etc).

I set users as parent table with UUID as the PrimaryKey, and profiles as child table with UUID as the PrimaryKey & ForeignKey (I don't know if this is possible, but migration runs without any error).

users_migration

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->uuid('id')->primary();
        $table->string('username');
        $table->string('email')->unique();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });
}

user_model

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use App\Traits\UUID;

class User extends Authenticatable implements MustVerifyEmail
{
  use HasFactory, Notifiable, UUID;

    protected $table = "users";

    public $primaryKey = "id";
    public $incrementing = false;

    protected $fillable = 
    [
        'id',
        'username',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}

profiles_migration

public function up()
{
    Schema::create('profiles', function (Blueprint $table) {
        $table->uuid('user_id')->primary();
        $table->foreign('user_id')->references('id')->on('users')->onDelete('restrict')->onUpdate('cascade');
        $table->string('full_name')->unique();
        $table->longText('address')->nullable();
        $table->timestamps();
    });
}

profile_model

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
    use HasFactory;

    protected $table = "profiles";

    public $primaryKey = "user_id";
    public $incrementing = false;

    protected $fillable = 
    [
        'user_id',
        'full_name',
        'address',
    ];

    public function user()
    {
         return $this->belongsTo(User::class);
    }

}

register_controller

public function Register(Request $request)
{
    $newUserData = $request->validate(
        [
            'full_name' => ['required', 'string', 'min:5', 'max:30'],
            'email' => ['required', 'unique:users', 'regex:(gmail)'],
            'password' => ['required', 'min:10'],
        ],
        [
            'email.regex' => "Your email must use Gmail as its domain.",
            'term.accepted' => "You must agree to Larasight's Terms and Conditions."
        ]
    );

    User::create([
        'username' => Str::lower($newUserData['full_name']),
        'email' => $newUserData['email'],
        'password' => bcrypt($newUserData['password']),
    ]);

    Profile::create([
        'full_name' => $newUserData['full_name'],
    ]);
}

Error upon registrating : SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value

Question : How to fill the user_id and full_name on profiles_table as the user registrates?

CodePudding user response:

I think you are doing this in an odd way. I would recommend just have an 'id' on your profiles table and have it as the primary. Rather than 'user_id' which is a foreign key be the primary. Anyways, besides that, when you create the Profile object you have not set the primary key. So you would either have to make it nullable in your profiles migration or new up a profile instance without persisting. Lastly, I guess you could just store the User::create() to a variable and pass the id as 'user_id' in the Profile::create function.

$user = User::create([
    'username' => Str::lower($newUserData['full_name']),
    'email' => $newUserData['email'],
    'password' => bcrypt($newUserData['password']),
]);



Profile::create([
    'user_id' => $user->id,
    'full_name' => $newUserData['full_name'],
]);
  • Related