This episode is for members only

Sign up to access "Build a Livewire CSV Importer" right now.

Get started
Already a member? Sign in to continue
12. Tracking imports with a model


After we've gone ahead and uploaded a file and hit import, once the validation has passed, the first thing that we want to do is create an import record in the database. This is going to help track the import so when we refresh the page or come back later,
we can fetch this record back out of the database and we'll see the current progress. Now, the import model itself won't deal with actually importing the data. What this will do is just provide a unique import with the path of the file, the file name, the amount of rows in the CSV, and the currently processed rows, as well as the date that it was
completed. So in this episode, we're just going to set up this import model, create it after we hit import, and see that in the database. Then once we move on to our queues and actually processing the CSV and upserting all the records, we'll update this model so we can basically grab the process whenever we need. Okay, so let's go over and create this model out. So we're
going to say php artisan make model import, we'll create a migration and a factory alongside that as well, and we'll head straight over to the create imports table migration. So think about the kind of data we'd need to store for an import. Now, first of all, this needs to belong to the user that's currently signed in, or if you're building a team app, then it will belong to the
team that you're importing for. So we're going to go ahead and add in a foreign ID for the user here so we can create a relationship. The second thing that we're going to be doing is just adding a really simple string in here for the model, you could set up some sort of polymorphic relationship here if you wanted to, but I don't think it really makes much sense. We just want to keep track of
the kind of model that we have here. So we can use a where statement to or where clause to grab the models for a particular thing we're uploading. And we'll see that a little bit later. The second thing is going to be the file path, just in case we need to try it again or re-zoom it at any point. So file path, and we'll also include a file name. Now, the file name is purely
for display purposes. We don't really want to show the temporary upload file name because that's a huge randomly generated string. So we want to include the original file name in here just so the user can see the actual file that we're uploading. So the second is going to be, or the two things that we need to do are two unsigned integers. They could be big integers depending,
but I don't think we really need them. And that's going to be the total rows and then the processed rows. So let's add them both in there. And we're going to default these to zero. And we don't need to default this because we're going to be inserting that when we create it. We just want to default the processed rows. And then finally, we'll finish off with a date time when this was
completed. So we'll say completed at, and we'll make this nullable because of course initially this will be null. It wouldn't have been completed. So that's pretty much all the data we need inside of our import table. Of course, you can add more later if you need to. Let's go ahead and migrate this and we'll get these created. Okay, so the relationship a user has many imports. That's
pretty much all we need for now. So let's go ahead and say imports, and we'll just create a really simple has many relationship in here and relate that to the import model. It's pretty much all we need to do. Okay, so over in our import component, once we have clicked import and validated, this is where we want to create that record. So let's go ahead and create out another method in here just
to keep this a bit separate. We'll call this create import, and we want to return this as well. So we're just going to use auth user. We'll access that imports relationship, and we'll go ahead and create an import. So what's the kind of initial data that we need here? Well, we need the file path. So that's going to be the actual path in case we need to presume it. We're going to need
the file name, which we're going to grab from the client uploaded name. We'll see how we do that in a minute. We're also going to have the total amount of rows as well. And we'll also have the models, the model we're currently working with. We'll start with model because that's easy. We passed that in earlier as a string. And again, you could set up a polymorphic relationship here, but I don't
think it makes too much sense. Just this is enough to get this working. Okay, so the file path, we've already accessed this. So that's quite easy. This file and get real path, that's to remember the path to the temporarily uploaded file within Livewire. And the file name, the real name of the file that we've updated is just get client original name. I mean, you can find all of these
methods in the classes that you have extending from the temporary uploaded file in Livewire. So just dive into each of these, even in the symphony uploaded file, and you'll find all of their methods if you need any more. Now the total rows is a little bit different. For that, we're going to need to be able to access the amount of records we have by reading the CSV and grabbing out all of
the records. So we're going to leave that just for now. We'll do that in the next episode. But let's just see how this works. So let's go ahead and invoke create import just here. And we'll see what kind of data we get in the database. So let's start fresh. We'll go ahead and upload a file here. Remember, this is called customers.csv. And of course, we can't proceed any further until
we have selected each of these. So let's go ahead and do that now. These are jumping a bit. So we'll figure that out in a second. But let's map all of these up and hit import. Okay, so yeah, we just need to add the fillable properties to our import. So let's go ahead and do that now. We can even make this unguarded. But let's set out our fillable columns in here. And just to make this easier,
let's reference the migration. So it's pretty much going to be all of these. So model, let's just copy and paste these over quickly. It's going to be the file path, the file name, and the total rows. And the process rows. And we should be good with just that. While we're here, what we could also do is add in the completed date. Or let's say completed at. And we could also, while we're here,
so we don't forget, cast this using eloquent. So completed at. We know it's a date time, so we want that to be converted to a carbon object. So we can add that into our casts as well. Okay, so that wouldn't have been created in the database. Let's try this again now that we've got them fillable fields in there. Choose customers. Map all of these up. Again, a little bit time consuming,
but not too much. Hit import. And there we go. That looks like it worked. So if we head over here to the imports, we've got our customer model, which we can use to categorize this. The reason that that's important is if we had another section where we're importing different data, so if we were importing users, for example, or product, then we'd only want to show the progress
for product uploads on the product import pop-up just here. So we're going to use that to separate them out. The file path, again, if we need to resume it, the actual file name for the user's benefit, and the total rows, process rows, and completed at, which all default. Now we're going to figure out this total rows now, and that's going to require a little bit of tweaking to
what we've already done, and we're just going to talk a little bit more about how we read the records, the actual records from the CSV to be able to get this. So let's head over to the next episode. We'll do that, and then we'll be ready to start adding in our queues to actually process and update each of these imports.
25 episodes2 hrs 20 mins


Let's build a powerful CSV importer with Livewire, completely from scratch. This can handle millions of rows, be reused for multiple models, and by using job batches, doesn't require the browser to be open.

This course is for you if:

  • You need a robust importer component for your models that you have full control over
  • You want to brush up on some advanced Livewire concepts
  • You want to learn about job batching and queues in Laravel
Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!


No comments, yet. Be the first to leave a comment.