Laravel Checkout: Database Transactions and Validation

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello guys today i'm answering another youtube comment which i received quite a long time ago a month ago and i finally have the time to create that mini project about card and checkout and doing a lot of actions in the controller which are related to each other like order products calculating quantities showing errors and all of that and for that i will use my own demo project from live wire kit but this demo is not about live wire so live wire is just for managing dynamic part so for example you can add to cart you can change the quantities and then at the end you can click checkout and checkout will calculate the card from the database and will perform a lot of actions and here we have a method of checkout and here i've made a comment what we will accomplish so this lesson is not about live wire it's about those things done in a step-by-step way with database transactions and error management so step by step first the situation before the checkout so by clicking these buttons and quantities in the database we have this one so product id and quantity and user id i'm logged in with user id 1 currently and by clicking checkout we need to take the card process that and then empty the card and this checkout method could be a controller so laravel controller like store of order something like that but in this case i continued with livewire method but again this lesson is not about livewire it could be a laravel controller with request so what we need to do check the product quantities in the products table there is a field called quantity left so we need to calculate the card quantity and compare that with quantity left and if there is at least one quantity that is not enough we need to throw an error before even creating the order so some kind of validation but instead of doing just validator of laravel we will do manual validation with error management so card would you cart where user id current user get then we do for each of the card as card product for example and we query the database for the actual product so product equals product find card product product id and then if we have the product and if quantity product quantity left is bigger or equals to card product quantity then it's okay right but in fact we need to do the opposite so if there is no product or if the product quantity left is less than quantity then we should throw an error in this case we're using live wire just the variable of checkout message which will appear and let's do exactly that this checkout message equals error product not found in stock something like that and let's try to simulate that so for example let's change quantity left of bar b to and in the cards we have that barbie with quantity one or let's increase that to quantity two and let's click checkout and see what happens check out our product not found in stock but if we change the product's quantity back to 10 if we refresh the page and click the checkout nothing happens no error and we will get to the actual success message but for now the first validation is clear the checkout message what we can improve here actually two things first we need to show which product is not found so what is the problem so product and then we do card product product name sorry it doesn't fit actually let's close the sidebar so card product name and then we need to load with product and this is a relationship and in cart model we have product with belongs to so product not found in stock let's simulate that situation again and if we refresh the page we click checkout and now product bar b not found in stock so that's one improvement and another thing i would like to improve is the amount of queries so for each of the product we make the query to the database this is not ideal let's make one query to the database to get all the products with quantities so products equals product select only the fields that we need so select id and quantity left get and we can even filter only those products that are in card so where in id equals and what is the array of card products card plug id or product id actually let's try it out i'm not sure if it would work let's edit that a bit so now we have all products with get but we don't need get we need actually plug plug off quantity left and id and let's dd those products so you will show the result so refresh the page check out and what is the value i will zoom it in so items id and quantity one two and four only those that are in card so one two and four in the card we don't have product id with id3 so that is the correct result and we can compare now so we don't need to have product find here instead of product here we have if not products product id from here so if it doesn't exist or in fact if not is set i think is the correct thing for the arrays or if product like this instead of product we have products with that index so like this and instead of having a lot of queries for each of the card item we have one query to the database well in fact two to get the card and to get all the products let's try it out if we refresh the page check out quantity left of non-object oh of course we need to remove that we don't have quantity left it's the value itself so refresh again check out product bar be not found in stock but if we change the quantity again back to 10 i think no error will appear refresh the page no error good so we improved the code that we have actually written just now and this is by the way my philosophy of creating products it depends of course on the budget on your team on a lot of things but usually what i tend to do is first write the code that works and then iteration number two think how to improve it so when you have something working that will be the first milestone which will force you to think how to improve it if you have no code there's nothing to improve and if you think in theory how it should be written in a better way you will likely be stuck but first write something and then improve that's my overall philosophy as a side note so we're finishing the check the product quantities so that's kind of a validation then if it's all good we create the order and for the order we have an order model order create and what are the fields let me show you in the order model there's user id and total price for now total price will be zero and we will recalculate it with a transaction so user id will be auth id and that's it for now we don't have total price it will be zero now we have order good next assign products to the order so for each of the same card so we can even copy for each of the card order products there's a belongs to many relationship create in the order not sure if you've seen that products belongs to many and with pivot table a few more fields quantity and price so product create which is card product product id and then array of pivot variables quantity equals card product quantity different variable name and then the price would be price card product product price like this and let's see if it's successful let's try to place our order again we refresh and we check out total price doesn't have a default value okay so let's assign total price to zero i thought i did it in the migrations but apparently i didn't total price is zero by default check out create is the array and given oh of course it's not create it's attached sorry belongs to many i will intentionally not edit this out because you will see that i'm a human too and i make errors and i make some nonsense mistakes because i don't remember the method name in this case okay checkout now no error and let's go to the database and we will immediately see the problem orders there are two orders but for order product there are values only for the order id two so the first error left the order which doesn't have products and that's why we need database transactions so database transactions are for the cases that you need like five different queries executed at once and if any of those fail the whole transaction will be rolled back so in this case an ideal scenario that order should have been deleted because order products failed so we will simulate that in a minute and we'll enter the code for the transactions but for now let's continue what is left to do assign products to the order this is correct then decrease quantities of the products and we can actually do that within the same loop so for each of the card we can do product find by cart product product id and then there's a method eloquent method decrement there's increment and decrement i'm not sure if it would work in this case but let's try it out card product quantity so decrement by quantity again let's try it out refresh the page do the checkout column not found oh of course decrement which field again i will not edit it out probably some hard morning for me to shoot that video because i'm doing quite a lot of silly mistakes so decrement the quantity left by the amount of quantity again let's refresh check out no error now and let's see the quantity left for our products here refresh it is decreased as it should be so good we are doing that in the same loop and this is done then empty the card so cart where user id auth id like this delete so that's another thing and then show success message which is the same this checkout message equals success okay and let's try the full thing out refresh again we do the checkout success and as you can see the card is automatically emptied this is livewire thing to re-render that part and let's see the orders are this is the order the cards should be empty and what we've forgotten to do is to calculate the total price so we should do that here so order increment total price by quantity times price quantity times price like this and let's try it out again refresh the page add something to cart add something else to cart check out success and let's see if the order has total price it does have the total price it is in cents so it's not a decimal it's an integer but this is probably the final thing that we should have done in that for each case in that checkout method and now let's introduce transactions for that we open the official documentation of laravel and in the section of database transactions in fact all we need to do to wrap up some sentences in a transaction is use facade's db so on top of our live wire component or it could be controller again we use db and then wrap everything here in db transaction or in fact we don't need to wrap this one because it's a validation but from here we do db transaction function and then inside we do all of that stuff of checkout success message like this or in fact we do need to wrap up the cart or we will add the card as a variable so function use card because that card variable is outside of this callback function what else we need to pass i think nothing else okay and let's make an error let's make some kind of a typo for example let's change the name of the variable and it will fail so the order should have been created but the product will fail and it should be all rolled back but we don't need to care about that it will be rolled back automatically let's try it out refresh the page add something to cart check out it will be an error unknown column quantity t but let's take a look at the database is there an order placed refresh there's no order record so it was successfully rolled back exactly what we expected but that's not all we need to take care about one more thing to gracefully handle the exception if anything happens in the database like query exception for example we need to add try catch and show the error to the user instead of having this or in case of debug true for example on env file if it's debug false actually on production they won't see that error let's see what will they see in case of that 500 server error which is nothing useful right so we need to wrap that db transaction into try catch so try then catch any exception basically with this checkout message you can do just generally error happened or you can include if you're brave enough you can include the message exception get message and let's try it out now so refresh check out and er happened of course you shouldn't show that sql state and exactly sql query so probably you should do something like error happened just generally or happened try again or something or contact us something like that so let's try it for final one more time or happen try again or contact us so this is what can be achieved with database transaction so if any of those fail then everything will be rolled back and with try catch on top we take care of the successful gracefully shown error message if you want more tips on laravel and general related stuff subscribe to the channel and you can support my daily mission financially by checking out one of the three products that you can see on the screen one of them is live wire kit which has that component of checkout price calculator which was the foundation of this demo project or you can check out other components also out of those three products we have quick admin panel generator and 20 courses on my teachable account and see you guys in other videos
Info
Channel: Laravel Daily
Views: 28,050
Rating: undefined out of 5
Keywords:
Id: LuxFql2CDyg
Channel Id: undefined
Length: 16min 23sec (983 seconds)
Published: Fri Jul 09 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.