Focus, everyone! As this is, by far, the most confusing part in the video for me. We're going to work with model and migration.
In this post, I covered from minute 1:10:05 until 1:28:10 of this video.
In our profile page, besides username, we have profile title, profile description and profile url. We can get the username from the User model, which holds all the data of a user. For additional data of a user, we need to use a different model. We're not going to put these additional data in the User model because 'user' and 'profile' are two different thing. So now, we're going to create a new model for user's profile.
Create a new model
To create a new model, we use the make:model
command. We also need to create a
new migration for that model because we need to describe something new in our
database. If we're going to represent something in our database, then we need
to describe it inside a migration file. If you view the help screen for
make:model, you can see that one of the options you can use is -m
which will
create a new migration file the model. Run php artisan make:model Profile -m
to create a new model and migration file for that model.
Describing the database in migration
We've created a model and migration! Let's open the new migration file to describe our database. This part gave me a little headache at first so to get a clear overview, I created a simple ERD.
One user has only one profile (1-to-1 relationship). A profile has a foreign key of user id. |
Now I'm clear on what we need to add in the new migration file.
14 15 16 17 18 19 20 21 22 23 24 25 26 |
public function up() { Schema::create('profiles', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('user_id'); $table->string('title')->nullable(); $table->text('description')->nullable(); $table->string('url')->nullable(); $table->timestamps(); $table->index('user_id'); }); } |
database > migrations > 2021_12_28_130508_create_profiles_table.php
Line 18: user_id
is used here and not other names to follow convention
because we're associating this to the id of the User model
Line 19:
Title is a type of string and the value can be null
Line 20:
Description is a type of text because user can input longer strings and the
value can be null
Line 21: Url is a type of string and the value
can be null
Line 24: index();
is for better searchability and
quicker queries
In the video, the instructor use unsignedBigInteger instead of foreignId on
line 18.
Based on this documentation of Laravel 7, unsignedBigInteger
is just the alias for foreignId
, to
indicate that the column is a foreign key. Both are useable but because by
default in Laravel 8, on line 17, is using $table->id();
instead of
$table->bigIncrements('id');
, I decided to use foreignId
.
Instruct Laravel to handle one-to-one relationship
Next, we need to instruct Laravel on how to handle the one-to-one relationship
of User and Profile properly. First, let's edit the Profile model. We need to tell that a profile is belong to User class so the
profile will be able to fetch the user data. Again, it is important to use a
particular name convention for the function name which is user
. Why
user
? Because it is referring to the User model.
8 9 10 11 12 13 14 15 |
class Profile extends Model { use HasFactory; public function user() { return $this->belongsTo(User::class); } } |
app > Models > Profile.php
Now, we need to do the inverse so that the user can fetch the profile data
too. We declared that the user has one Profile class. Again, follow naming
convention which is profile
for the function name because it is referring to
the Profile model.
45 46 47 48 |
public function profile() { return $this->hasOne(Profile::class); } |
app > Models > User.php
Manually inserting data to the table
Everything's ready. If you still remember, if we want to interact with out
database, we do it with Tinker. Now, before we insert user's profile data
manually with Tinker, remember, whenever we described something new in the migration file, we need
to run migration with php artisan migrate
. Else, you will receive this kind of error when
you want to save changes in Tinker later:
[Illuminate\Database\QueryException] SQLSTATE[HY000]: General error: 1215
Cannot add foreign key constraint (SQL: alter table `priorities` add
constraint priorities_user_id_foreign foreign key (`user_id`) references
`users` (`id`))
After migration is complete, enter these commands one by one.
php artisan tinker
- enter Tinker-
$profile = new Profile();
- you can also write it as$profile = new App\Models\Profile();
, like was taught in the video. This is to create a variable that creates a new Profile -
$profile->title = 'Cool Title';
- This will insert 'Cool Title' as the profile title -
$profile->description = 'Description';
- This will insert 'Description' as the profile description -
$profile->user_id = 1;
- Assign this profile to user id of 1 because if you save without assigning it, you get an error asuser_id
cannot be null $profile->save();
- Save changes made
DB::table('profiles')->truncate();
. All data will be cleared
without actually deleting the table.
Displaying the data to the view
In Part 6, we've learned how to fetch the data to the view. We need to the
same this time but there's a tiny difference. Because we want to display the
profile that belongs to a user, we need to specifically tell Laravel
the table name. For example: {{$variableName->tableName->columnName}}
9 10 11 12 13 14 15 16 17 18 19 20 21 |
<div class="col-8"> <div> <h2 class="font-weight-light">{{$user->username}}</h2> </div> <div class="d-flex pt-4"> <div class="pr-5"><strong>4</strong> posts</div> <div class="pr-5"><strong>165</strong> followers</div> <div class="pr-5"><strong>176</strong> following</div> </div> <div class="pt-3"><strong>{{ $user->profile->title }}</strong></div> <div>{{ $user->profile->description }}</div> <div><a href="#">{{ $user->profile->url }}</a></div> </div> |
resources > views > home.blade.php
Save changes and view the site. You can now see the title and description of your profile changed to the value that you inserted.
Alternative way to insert data manually
Our url is currently empty, right? Let's try to run these:
$user = User::find(1)
- Display the user with the id of 1$user->profile
- Display the profile of that user
$user
not $profile?
So if you use $profile->url =
'yourwebsite.com';
you definitely will encounter an error because $profile
is
not declared and you're editing the User table. To insert data to Profile
while in the User table, you use $user->profile->url =
'yourwebsite.com';
. After inserting it, you cannot save it with just
$user->save();
because that will save the table for User. You would want to
save the Profile table because url is in the Profile table. To save the
Profile table, simply use push();
. The final command would be
$user->push();
Everything is saved! Now open the site and you should see something similar to this.
No comments:
Post a Comment