25
Week 3 of 100DaysOfCode Laravel Challenge
I considered this episode a suitable candidate for a separate post. Please see below
In our single post route definition Route::get('/posts/{post}', function(){...}
we used the wildcard {post}
to match slug of the post. We used the regular expression ->where('post', '[a-z\-]+')
constraint to allow only alphabets and the hyphen character. So, if a route request doesn't comply with the constraint, will be aborted with a 404
error.
In this episode we remove this constraint from the route and handle the post-not-found logic in our Post
model. We catch the slug in our Model class find()
method, find a post by that slug, if the post exists, we return it, else return a ModelNotFoundException()
.
Contributed to the Blog Project on GitHub.
Every application needs some sort of environment-specific configurations, and so does Laravel. Laravel environment-specific configurations are stored in the .env
file at the root of your project. This is a private file included in .gitignore
. That means we don't want the contents of this file to be exposed to the world.
Environment variables are stored against some keys in this file. Laravel then uses the helper function env(KEYNAME, DEFAULT_VALUE)
to access stored value. If the key is not set in the env file, it returns the default. For example, env('DB_CONNECTION', 'mysql')
will look for the key DB_CONNECTION
in env file, if set, will return the value, else return the default mysql
.
Next, we connect to our MySQL database and create a database Blog
. We run the command PHP artisan migrate
, migrations are run and the tables are created. You can show
the created tables in the CLI by running the commands use Blog
and show tables
.
MySQL -uroot -p
CREATE DATABASE Blog
PHP artisan migrate
use Blog
show tables;
Laravel, out of the box, provides migrations for some tables like:
users
migrations
password_resets
failed_jobs
In the previous lesson we ran a command php artisan migrate
which made some tables in our database. Let's look at the users table out of these. This table has some columns like name
, email
, password
, and some indexes like the primary key
index and the Unique
key index. But where is this structure defined in our application?
Browser the database/migrations
directory. This folder contains some PHP files that are basically PHP classes with two methods, up()
, and down()
. The up()
method is for running the migration php artisan migrate
, and the down method is for rolling back the migration php artisan migrate:rollback
. The rollback command rolls back the last migration run.
Another command is the php artisan migrate:fresh
. This command drops all of the tables from your database and then runs all migrations. As it drops database tables before running the migrations, the data from your database is lost. So, be careful and don't run this command in production. For practice, change your APP_ENV
variable to production the env
file and run the command. It will give you an alert that you are in the production.
In Laravel, every database table may have a corresponding Model class. For example, for our users
table discussed in previous episode, there is a model called User
in App\Models
. This is called Eloquent Model in Laravel. Every instance of this class represents a record in the users
table. This is Laravel implementation of the Active Record pattern.
Let's play with some basic API functions of the Eloquent Model.
Boot up your tinker by running the command php artisan tinker
.
use App\Models\User;
$user = new User;
$user->name = "Arif"`
$user->email = "[email protected]"`
$user->password = bcrypt("@r!f");
$user->save()
User::find(0)
User::findOrFail(1)
$users = User::all()
$users->pluck('name') // will return a new collection of names
$users->first()
$users[0]
In the Previous episode we created a Post
class to deal with our file based database of Blog. Now we delete that file and create an Eloquent Model. Also, we will generate a migration for the posts
table. We can generate both the migration
and model
in a single command but for now we use two separate commands.
php artisan make:migration create_posts_table
php artisan make:model Post
The make
command is used to generate files, e.g. models
, factories
, or migrations
. The command php artisan help make:migration
will list all details about the command. The migration name should describe the task it does. Notice the plural name posts
in the migration name, that is a convention.
php artisan make:model Post
will generate the Post Eloquent mode. Notice the singular name Post
. Unlike the plural name posts
of the migration class, the model class has a singular name Post
, which is also part of the convention.
In the migration file up()
method add the posts table fields. You can check the field names from your Yaml front Matter
section of your file based blog posts.
--------
title: My Fifth Post
slug: my-fifth-post
excerpt: Lorem Ipsum is simply dummy text of the printing and typesetting industry.
date: 2021-12-03
--------
<p>Lorem Ipsum... </p>
Run php artisan migrate
command for creating the posts
table from the newly created migration class. Now add some data to your table by playing with the Eloquent API.
Boot up tinker php artisan tinker
.
$post = new App\Models\Post;
$post->title = "My first Eloquent Post";
...
$post->save(); // Persist changes
In your single post route, change the wildcard from slug Route::get('/posts/{post}', function ($slug) {
to id Route::get('/posts/{post}', function ($id) {
. Update the view posts.blade.php
accordingly, from <a href="/posts/{{ $post->slug }}">
to <a href="/posts/{{ $post->id }}">
.
Delete the file based posts folder resources/posts
as we are now fetching posts from database, not from files.
Boot up tinker php artisan tinker
and play with the Eloquent API as:
use App\Models\Post;
Post::all();
Post::first();
Post::find(1);
Post::all()->pluck("title");
Contributed to the Blog Project on GitHub.
At this point, if visit our single blog post /posts/my-first-post
, you notice that the text is compact and has not formatting. That is because now we are not fetching the post from files that had full html formatting like the <p>
tags around text blocks.
Now the body of our blog post is coming from a database table field. So, lets update the body
column in our database to add the p
tags around it.
Boot up tinker php artisan tinker
and run the following commands.
use App\Models\Post;
$post = new Post;
$post->body; // will print the current content of the body column
$post->body = '<p>'. $post->body .'</p>';
$post->save(); // persist the changes
Repeat the same for all posts.
In our post.blade.php
file, we have disabled the default escaping of HTML tags by using the Blade syntax {!! $post->body !!}
. You should disable this escaping only if you are in control of your content. It means you should not disable escaping for user supplied content because users may input malicious content. For testing, save <script> alert("Hello"); </script>
to your post body and reload your post page. You will see the JavaScript alert popup.
I considered this episode a suitable candidate for a separate post. Please see below
Thank you for following along with me. Any suggestions/advice for improvement will be appreciated.
~ Happy Coding
25