Week 3 of 100DaysOfCode Laravel Challenge

Ep#15: Blade Layouts Two Ways

I considered this episode a suitable candidate for a separate post. Please see below

Ep#16: A Few Tweaks and Consideration

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.

Section 4 of Laravel 8 from Scratch Series on Laracasts: Working with Databases

Ep#17 Environment Files and Database Connections

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

Ep#18 Migrations: The Absolute Basics

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.

Ep#19 Eloquent and the Active Record Pattern

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]

Ep#20 Make a Post Model and Migration

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.

  1. php artisan make:migration create_posts_table
  2. 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.

Ep#21: Eloquent Updates and HTML Escaping

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.

Ep#22: 3 Ways to Mitigate Mass Assignment Vulnerabilities in Laravel

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