Introducing Sushi Package0:00
I love sushi, so it's no wonder that I also like the next package called, surprise, Sushi. It's a package by Caleb Porcio, which you might know from his small projects like Livewire or Alpine.js. Just kidding, great guy. So let me tell you more about Sushi. We're now looking at the website of Sushi, which, by the way, looks just beautiful. Just a great job, Caleb, and you can see here already Eloquent's missing array driver. So I think, I hope that you already know it. If you don't know it, you maybe can already guess what it is about. So it's kind of Eloquent, but without a database because we're using an array where we can
Installing and Creating Location Model0:37
If you don't know it, you maybe can already guess what it is about. So it's kind of Eloquent, but without a database because we're using an array where we can define our data. So let's see, how can we get this started? First we're going to install it. And then we're going to add a trait to our new model, which is Sushi. So let's give it a try. Let's install the package. And in our case, we want to work with a new model, and I'm using Idea to do this. That's the interface that you're currently seeing, and we want to add location.
And in our case, we want to work with a new model, and I'm using Idea to do this. That's the interface that you're currently seeing, and we want to add location. So we're working with Users here, and every User belongs to a specific location. So this is our use case here. And our locations, we don't want to store them in the database for a few reasons. And one of them is that we want to define them through an array. And one big advantage is that it's way easier to handle and to change. So let's take a look. What do we want? We don't want to add a migration, that's what we don't need.
What do we want? We don't want to add a migration, that's what we don't need. We don't need a factory. Maybe later, let's see. And I think that's just it. Actually, we just want to get this new model. All right, here we are. And the second step, if I remember correctly, was to add now this trait, Sushi. All right, let's bring this in here. So this now tells Laravel that, yeah, we want to work with an array.
Defining Rows Array Data1:52
All right, let's bring this in here. So this now tells Laravel that, yeah, we want to work with an array. And of course, now we also have to provide this array, and we can do this right here in this class. And Sushi will look for a property called rows. So I have here a bunch of rows already, which you can see here. So these are our locations here. We can define here in the array anything we want. And in our case, we have some locations with a name for New York, with a code, and also with an ID.
And in our case, we have some locations with a name for New York, with a code, and also with an ID. And we have different locations, New York, Los Angeles, San Francisco, Chicago, and Seattle. And as you can see already, it's pretty nice to define some data directly here in your code, and you don't have to think about how to put it in your database, how to change it, and things like this, because we're going to do this right here in this class. All right, how can we test that this is even working? And I have already a test for creating a new User, which is called it can create a new User. And let's see if this is working.
Testing Sushi Model Queries2:55
new User. And let's see if this is working. It is. By the way, we're just creating here a simple User. And now let's copy this whole test here. And by the way, we're using past here for testing. And let's create a new test called it can create a user with a location, because this is our end goal here. We want to create a new User with one of our location. And this should be a relationship between a model User which sits in the database and
We want to create a new User with one of our Location. And this should be a relationship between a model User which sits in the database and Location which is just an array. All right, let's get rid of everything here. And what I want to do is I want to first see if this even works. So let's dump out just all of our locations. So this is how I would do this with Eloquent. Let's run this test. And voila, we can see here a collection, Eloquent collection with an array, five items here. And we have them all here.
And voila, we can see here a collection, Eloquent collection with an array, five items here. And we have them all here. So this seems to be working, which is already pretty cool. But just thinking about that, we just added a straight here, defined the data. And yeah, this Eloquent method all is working as we are used to. Okay, so far so good. But let's also try to use this. Now let's copy this test here. And we want to do something similar. So what we want to do here is to work as if our locations were just another Eloquent model.
And we want to do something similar. So what we want to do here is to work as if our locations were just another Eloquent model. So this means when someone creates a new User, we want to get through this form here or however we get the data, the location code, which again is like a code for our location. And let's say this is just one, two, three, four. All right. Then we are, yeah, we're posting this. We want to make sure that the response is okay. And then we want to make sure that we have now a new User in the database. And then our User should have a locationID.
And then we want to make sure that we have now a new User in the database. And then our User should have a location_id. And here we want to see the ID of our location. So let's get back here. Let's take maybe Los Angeles has the ID two, but this means we also need to change the code here. So we're providing the code here, LA123. And we want to see in a database now this relationship from a User to a Location with the ID of two. Let's try it out.
Mapping Location Code to ID5:16
the ID of two. Let's try it out. Of course, we know that this should fail now because here we don't see the result. What we already have inside our database is the location_id field. So this is what I have already prepared, but we only found an item where this is now. All right, let's see how we can fix this. There is a CreateUserController, which we have to take a look at. So first here we are validating our input, and we also want to make sure that we see here our location_code. So let's say our location_code is also required.
here our locationCode. So let's say our locationCode is also required. And then to make this work, we're going to need to change here now the data array. And we're going to say here we want a new field called locationId. And this we get by calling the location where code is the code which we just got through dataLocationCode. And here we want to get the first one, exactly how we would do it with an Eloquent model. And then we want to get the ID. And then we also need to unset the locationCode from the array because we don't want to use this anymore.
And then we also need to unset the location code from the array because we don't want to use this anymore. All right, let's see if this works. Let's go back to our test. Let's run this, and it's already passing. Okay, how cool is this? Let's see if we can break this, what if I change here the code? It's failing because now we try to access id on null, which happens here. Because this only works, of course, if we find a location, but we can do this even better here by providing a new rule.
Because this only works, of course, if we find a Location, but we can do this even better here by providing a new rule. Because even though we're working with Sushi here, we can also use rules like the exists one. So we want to make sure that this Location code exists for our Location. So we need to provide here the full namespace of our model, App\Models\Location, and then we also need to define that we want to look for the code column. So again, let's go back to our Location. We have here a column called code, this is now where we want to check if this code exists. So this means we should now see a different error in our test.
We have here a column called colon, this is now where we want to check if this code exists. So this means we should now see a different error in our test. It should still fail because this code does not exist. And now we get a different error, the selected location code is invalid. And how cool is this? We are not working with a database model, which sits in that database, but still we can make checks like this to make sure if a specific value already exists. So this is super cool, and I really love how this is working. Just to be sure, let's fix our test again, we want to make sure that we're using a code that exists like LA123, and now the test is passing.
Just to be sure, let's fix our test again, we want to make sure that we're using a code that exists like LA123, and now the test is passing. And that's how easy it is to create now a new model that works with the data inside the model itself like this one. Let's take a look if there's anything else we want to touch. So nope, not here. But let's also go to the repository because there are a few things I want to mention here as well. Let's go through, we already talked about the rows where we define this. We already talked a little bit about relations, but let's do this as well.
Relationships, Schema, and getRows8:51
Let's go through, we already talked about the rows where we define this. We already talked a little bit about relations, but let's do this as well. So let's go to our User model here, and I can define here a relation. So User has a location, and this will be a belongsTo relationship. This belongsTo, and then we provide our model. And just to be sure that this is working, let's get back to our test as well. And here after we have created a User, let's dump out the first User, and let's try to find the location for this User. And if the relationship works, this should work too. And fair enough, we see here Los Angeles, so this is working as well.
And if the relationship works, this should work too. And fair enough, we see here Los Angeles, so this is working as well. All right, so we talked about relationships, that's also nice. And two more things that I wanted to show you. Yeah, first, sometimes if the schema auto detection for sushi, if this does not work as you want to. So this means by default, sushi needs to check, okay, this is an integer, this is a string, this is a string, and some things like that. And if this is not working, you define a schema yourself where you can say, no, it is not an int, maybe this is a float.
And if this is not working, you define a schema yourself where you can say, no, it is not an int, maybe this is a float. And then you can define this even more specific how you want it to be. And there is one more thing here, which is called getRows. So what this means here, let's copy this, inside here, instead of providing here this property array called rows, what we could also do is we could provide here a method. And I think this is this example from the docs isn't even that good, because this looks very similar to what we did before. But of course, here we have some more functionality, because it's not only an array, we have here some space where we can run some operations.
But of course, here we have some more functionality, because it's not only an array, we have here some space where we can run some operations. So what you also could do is you could call an API, get some data from somewhere else, and then create here, this array, and return it. I always hate when I see those yellow underlines here in phpStorm. I want to make phpStorm happy. So this looks better now. So yeah, you can define also the rows with a function where you are more powerful because you can define yourself where to get the data and how to prepare it. And then in the end, you're going to still return an array.
you can define yourself where to get the data and how to prepare it. And then in the end, you're going to still return an array. But it's very useful to know that this method also exists. Sushi is an array driver for Eloquent, where your data is stored, not in the database, but inside an array in your code. I use Sushi if two situations are true. First, the number of rows are limited, for example, for cities, rows, or time zones. And second, when I want or need to change those within the code and not for the database. Thank you, Caleb.
And second, when I want or need to change those within the code and not for the database. Thank you, Caleb.
