I'm trying to extend the User model with another table (Profile) to get the profile picture, location, etc.
Can I override the User model's index()
function to do this?
Current model code:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; protected $fillable = [ 'name', 'email', 'password', 'user_group' ]; protected $hidden = [ 'password', 'remember_token', ]; protected $casts = [ 'email_verified_at' => 'datetime', ]; }
P粉3788901062024-01-11 15:21:01
What you want to do is create a relationship between the User
model and the new Profile
model. To do this, you first need to create a model Profile
and its associated Tabble profiles
php artisan make:model Profile --migration
There should be a file named 2022_11_28_223831_create_profiles_table.php
in
database\migrations
Now you need to add a foreign key to indicate which user this profile belongs to.
public function up() { Schema::create('profiles', function (Blueprint $table) { $table->id(); // $table->string('path_to_picture') // user id $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->timestamps(); }); }
Now add the following functions in your user model
public function profile() { return $this->hasOne(Profile::class); }
In your profile model
public function user() { return $this->belongsTo(User::class); }
Run php artisan migrate
and everything should work as expected
If you want to test whether the relationship works as expected, create a new test case
php artisan make:test ProfileUserRelationTest
attests\Feature\ProfileUserRelationTest.php
<?php namespace Tests\Feature; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; use Tests\TestCase; use App\Models\User; use App\Models\Profile; use Illuminate\Support\Facades\Hash; class ProfileUserRelationTest extends TestCase { use RefreshDatabase; public function test_the_relation_between_user_and_profile_works() { $user = User::create([ 'name' => 'John Doe', 'email' => 'jd@example.com', 'password' => Hash::make('password'), ]); $profile = new Profile(); $profile->user_id = $user->id; $profile->save(); $this->assertEquals($user->id, $profile->user->id); $this->assertEquals($user->name, $profile->user->name); $this->assertEquals($profile->id, $user->profile->id); } }
Now you can run php artisan test
to see if everything is fine.
CautionThis will refresh your database! So don't test in production.
The output should be like this
PASS Tests\Unit\ExampleTest ✓ that true is true PASS Tests\Feature\ExampleTest ✓ the application returns a successful response PASS Tests\Feature\ProfileUserRelationTest ✓ the relation between user and profile works Tests: 3 passed Time: 0.35s
Learn more about relationships in Laravel: https://laravel.com/docs/9.x/eloquentrelationships
Learn more about migration: https://laravel.com/docs/9.x/migrations
alternative plan
$user = User::create([ 'name' => 'John Doe', 'email' => 'jd@example.com', 'password' => Hash::make('password'), ]); $user->profile()->create(...); // replace the ... with the things you want to insert you dont need to add the user_id since it will automatically added it. It will still work like the one above.