Creating, Editing and Deleting Posts
Now for the meat of the project, creating posts with content and file storage and upload.
Like the same as adding subweddit functionality, we need a model, controller, factory and migration.
The design of the Posts table is as follows:
A post will have a title, body, an id and a foreign key user_id, set as the creator of the post, who will be perform edit and delete actions on the post.
We can now fill the database table with mock results
it was at this point I forgot to add subweddit_id (the subweddit the post belongs to) to the post table! time to make a migration
after adapting the factory, I was able to add a mock row in the database
Changing the subweddit_id of the post using phpMyAdmin allowed me to simulate a post from the first subweddit so I can test a show() method in SuubwedditController
At this point I had this in my SubwedditController:
Notice - getFirstOrFail() - method call - this will find the first post where the subweddit_id is equal to the subweddits id, then continue, if not then it will fail. Overall this design could be cleaned up and refined.
getFirstOrFail() was suitable to find the first result, but not if we have an array of posts, which we will in a real world. Instead, it is preferable to use ->get() - which will return the full array of posts associated with that subweddit.
Before we progress, a revision of my routes is in order. at the moment when I want to access a subweddit, I'm creating an object and searching for the subweddit using the value given in the wildcard manually. Works, but can be improved upon. Instead of declaring the subweddit by locating a subweddit that matches the name in the URL, we can use Laravel route model binding. By default, when passing a wildcard value from route to controller, Laravel thinks its being passed an id. So, if this suits the method, it can be picked up by declaring ' Subweddit $subweddit ' for example, then you have obtained the object by its id.
But say you don't want a bunch of Id's in your URL, and want a name or a title instead, all you have to do is declare the wildcard as such in the routes file (e.g. {subweddit:name}
Using php artisan tinker will allow us to create a few more factory posts as tests.
App\Models\Post::factory()->create(['subweddit_id'=>1])->count(5);
This will create 5 posts with the subweddit id of 1.
we can use dd, or dump and die to view the results! lets browse to our test subweddit to check.
Displayed is an array of 5 App\Models\Post, if we open these arrays we can see the associated attributes, one being the subweddit_id, which matches 1, so we have successfully captured that subweddits posts!
Now we can work on creating our own subweddit posts.
Using this handy blade feature we can create a snippet file, which in this case will be the 'create post' bar, and link to it within the subweddit blade, just to clean things up a bit
When you click on the create post panel, it will link to posts.create which will show a form for creating a post (simpler than making a post within the subweddit page itself for the moment)
This form will take in the users data and send a post request to w/{$subweddit->name}. which will be picked up in the routes file as:
and the store method in Postcontroller:
Which receives the post request then attaches them to a new Post object, finally collecting the updated collection of posts and returning the user to the subweddit with the post now showing.
Now lets perform the 'UD' of 'CRUD'. to begin updating, we will make a new blade form within our posts folder called 'update'.. this new file will contain the same content as 'create' except the values will be the current values of the post, and the request is not a POST request - it is now a PUT.
We can capture the current values by stating that the value for the input is {$post->title} for example. This edit form will call the update method in postController.
This method identifies the post in question and sets the title, and body to the request title and body, then calls ->save() to save the details.
To delete, we don't need a whole new page, all we need is a small icon as a delete request.
Though, if the post has spaces in it, the url is messy as it includes %20 as spaces, so it would be handy to include a slug for a cleaner url. I made a migration to add a string 'slug'.
then in the postcontroller store method we can import the laravel method 'Illuminate\Support\Str' to create a slug like so:
now we can access the posts slug!
A cool feature added too was displaying the time since creation. this is achieved by this line of code in the blade:
{{$post->created_at->diffForHumans()}}
· which, like the name suggests, shows the difference in a human readable way.
Comments
Post a Comment