Posts

Showing posts from December, 2020

4. Defining Relationships Between Posts and Users

Image
After creating the posts table migration, I then defined the relationship that a post has with a user, which is that many posts can belong to one user - this is achieved with the belongsTo() method. To make the relationship function more semantic, I've named it author - as writers of posts would be considered as authors. For this reason, I also had to specify the foreign key, instead of letting Laravel assume that it was author_id - which doesn't exist. Below is a screen capture of the relationship in the post model (App/Models/Post.php).  The flip-side of this is on the user side, where I need to state the inverse relationship. In this case, one user can have many posts - this is defined with the hasMany() method. Below is a screen capture of the relationship from the user model (App/Models/User.php).

5. Updating the Routes in web.php

Image
Before I begin adding methods to the PostController.php file, I will create all of the necessary routes in the web.php file, located in the routes directory. These routes will determine the methods in the PostController where users will be directed to. It should be noted that some routes were automatically added by the authentication scaffolding. The GET request for '/' returns the welcome view (welcome.blade.php), which is a landing page, was added by the scaffolding. The GET request for '/home' returns the home view (home.blade.php - i.e., a dashboard) for logged-in users, again added by the scaffolding. Finally, the 'Auth::routes();' line was also added by the scaffolding. Below is a screen capture of the web.php routes file. It should be noted that precedence does matter in the routes file. For example, the GET request for '/posts/create' must come before the wildcard GET request for '/posts/{post}'. Otherwise, the word 'create' would...

6. Implementing CRUD Functionality in the PostController

Image
To implement CRUD functionality on posts, I will make changes to the PostController.php file. These changes involve adding the following methods to the PostController: index() - Returns a view showing all of the posts. show() - Returns a view showing a single post, based on an id. create() - Returns a view with a form to create a new post. store() - Persists the values from the create form's POST request to the database. edit() - Returns a view with a form to edit an existing post, based on an id. update() - Persists the values from the edit form's PUT request to the database, based on an id. destroy() - Deletes a post from the database, based on an id. I have also added a reusable validation function at the bottom of the post controller file, which can be seen at the bottom of this blog post - this function is used as part of the store and update functions. Index function: In the index function, I will retrieve all of the posts using get(), which will be ordered by the most r...

7. Adding Views for Posts

Image
 To fully implement the functions in the post controller mentioned in the previous post, it is necessary to create views associated with each function. Post index (resources/views/posts/index.blade.php): This view shows all recent posts, created by all users - only the post heading and some minor details (author and publish date) are shown in this view. This view will be accessible by all users (guests and authenticated users). Users can click on a post image or heading to be taken to the post show view. (Note: This screen capture had to be retaken after the tag functionality was implemented.) The code snippet below is from the post index view. Posts are looped through using the @forelse tag. An @if tag checks to see if the current post has an associated image, if not, a placeholder image is used. Posts without images make use of a placeholder, which differs depending on whether the post has an odd or even id. Post show (resources/views/posts/show.blade.php): This view shows a fu...

8. Making Factories to Generate Users and Posts

Image
In Laravel, factories can be used to generate data for database tables, which is very useful while testing an application that is in development. It can also be used to prepare an app for production, where certain tables may require data prior to launch (such as tables that do not store user input). A user factory (database/factories/UserFactory.php) is already included in the code due to the scaffolding, however, I need to adapt it to match my requirements. The screen capture below shows various values being faked to create valid database entries. The configure() method contains a function which interacts with the post factory (database/factories/PostFactory.php). After a user is created, a new post is also created using the new user's id as the post's user_id foreign key. To generate a post factory, I run the following command: php artisan make:factory PostFactory The post factory (database/factories/PostFactory.php) creates faked data for a new post. As mentioned above, this...

9. Adding Authentication to Routes

Image
In Laravel, it is rather straightforward to implement authentication. My approach involved adding authentication middleware to the appropriate routes that required authentication: ->middleware('auth') The middleware was only added to routes that required users to be logged in. In my case, guest users are allowed access to the welcome page view (resources/views/welcome.blade.php), accessed at '/'. Guests are also able to access the '/posts' URI, which returns a view showing all of the blog posts (resources/views/posts/index.blade.php). Finally, guest users are able to access the 'posts/{post}' URI, which uses a wildcard - this route returns a view showing a single post (resources/views/posts/show.blade.php). In addition to the routes accessible by guests, which were implemented by myself, additional views and routes were generated by the application scaffolding. As an example, guest users are able to access URIs such as '/login', which returns ...

10. Implementing a Tag System for Posts

Image
I wanted my blog application to make use of a tag system, so users can add tags to their posts and also filter posts by tags. To start implementing a tag system, I need to create a tag model and a database migration, this was achieved by running the following command: php artisan make:model Tag -m The screen capture below shows the create_tags_table migration. This migration creates two tables - a tags table and a post_tag pivot table. An intermediate pivot table is required in order to facilitate the many-to-many relationship between posts and tags. The name field in the tags table will represent a tag name, such as 'Fishing' or 'Golfing'. The post_tag table will have 2 foreign keys: post_id, which references the id in the posts table tag_id, which references the id in the tags table Both of the foreign keys will cascade through the database - if a tag or a post is deleted, the associated row in the post_tag table will be deleted. Next, I will define the relationships ...

11. Implementing Authorisation and Adding Admin Users

Image
My next step is to implement authorisation so that users are only able to edit and delete posts they have created. To achieve this, I will make a post policy (app/Policies/PostPolicy.php), using the following command: php artisan make:policy PostPolicy --model=Post This command creates a new policy directory, a policy named PostPolicy and associates it with the post model, using the --model flag. Two functions require authorisation - the updating and deleting of posts. To add authorisation to these areas of functionality, code has to be inserted within these sections of the post policy. This can be seen in the screen capture below: These functions will return either true or false, depending on whether or not the current user's id is equal to the user_id foreign key of the post they are currently trying to update or delete. Now the above logic needs to be applied to the post controller in the edit, update and destroy functions through the use of a gate: abort_unless(Gate::allows(...

12. Generating Tags, Users and Tagged Posts with a Seeder

Image
At this stage in the blog project, I wanted to create a database seeder which utilises a tag, admin and user seeder. By running a single command, I would be to generate my chosen tags, an admin user and X number of normal authenticated users. To start with, I created a tag seeder (database/seeders/TagSeeder.php). This seeder populates the tags table with 10 tags, each having a unique name. This can be seen in the screen capture below: Next, I had to adapt the user factory and include parts of it within the user seeder (database/seeders/UserSeeder.php). The user seeder, makes use of both the user and post factories. The user seeder will create 20 users, each having 3 associated posts. Each of those posts will have between 1 and 6 tags attached to it, reflected in the post_tag table. Because I know that I have 10 tags, I am able to 'shuffle' the possible tags and assign a random number of tags (between 1-6) to each post. As a lengthy function, I made sure that I fully commented t...