Home  >  Q&A  >  body text

Enhance user model

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粉311464935P粉311464935306 days ago327

reply all(1)I'll reply

  • P粉378890106

    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.

    reply
    0
  • Cancelreply