2.9 Active Model Serializers
In order to optimize the way data is serialized into JSON, we’ll use Active Model Serializers. This will allow us to gain more control over data representation.
1.Introduction3 lessons, 12:00
1.2Model Our Business Data05:37
1.3Installing Rails API04:16
2.Building the API10 lessons, 1:53:48
2.3Adding Items to Orders14:45
2.4Payments and Receipts11:05
2.6A Refactoring Opportunity13:34
2.9Active Model Serializers08:51
2.10Documenting Your API14:07
3.Conclusion1 lesson, 01:08
2.9 Active Model Serializers
We have reached a solid point in our application. We have everything from setting the tables up, to the orders, allow customers to add in new items, so they can enjoy their meal, and also how to pay for those orders. We also send an email with the receipt to the customer, because we have information on their email, and so that feature is possible to achieve. Now, I want to introduce you to a tool that basically allows us to manipulate our data that's being rendered. As you see here in line six, I have a list of orders, and I'm rendering the JSON without any control over those orders or the way they're displayed. So if I resort to the curl command and list all of those orders, so, let's see, local host, 3000/orders, and press Enter, you will most likely see more information that you wish you had. For example, the time stamps might now be the best for whoever's consuming the API. If you think this is good enough, then by all means. But what if you want to customize the output based on the model? That is when active model serializers come in. This gem basically manipulates the content that's being put out. Lets open our gem file really quick and insert this new gem. Its. It's called active_model_serializers. There you go. There's just one slight variation that I need to introduce. We need to resort to the GitHub branch really. So just retrieve the gem from the GitHub repository as the master branch from the time of the recording has some changes that otherwise would compromise our application. So there's some bugs in the gem that's released now, so just retrieve the master branch from GitHub. From here we can type in the bundle command to update the changes, and then we just need to generate a serializer. There's really nothing else to be done. Active model serializers contain some rails related code that will interact very closely to this render json command. So let's do it. Let's type in rails api g and then serializer. Since I want to change the way the orders are formatted, I'll create an order serializer, just like you see at the bottom. Pressing Enter, you will see only one file. Well, that's just what it is, we only need this file. Nothing too fancy, no Bootstrapping at all, just the serializer. As you can see the default is to rely on an attributes ID call, which will basically render the ID and nothing else. No relationships, no extra attributes, it really depends on your taste. Now as with any other change in the gem file, we will need to restart the server, and then we can safely call the curl command to list our orders. When we do it, you will see two different orders, which we had, and then with just the IDs, there you go. Now if I want to, I can add in multiple attributes such as a name and email. This will make sure that only these three attributes are rendered and the timestamps are left behind. If I do this and reload the request, you will now see the email and the name. Awesome, this is actually pretty good. But how about the table reference? Is there anything we can do around the table? Well, you can always pass, for example, the table_ID. This is totally fine. However, this is really something that, I don't know, it could be better. Just referencing the tables_ID might not be the best solution for you. So what if you want to display the data around the table as if it were in a relationship? If we use belongs_to table you will see something different. If I type it in, you will see the object that contains the entire table as if it were a normal JSON rendering. So the ID number, number of seats and the time stamps are there. But here's the thing, if we create another serializer, let's see, let's generate the serializer for the table. There we go. Now if we choose to edit it, let's see, there it is. As you can see, the table serializer only has the ID. Now, if I choose to run the same kernel command, you will see something different. Instead of rendering the entire set of data for the table, it actually uses the serializer we've just generated. That's pretty cool, right? In here, let's say, for example, you just want to know the number of the table or even the number of seats. Maybe, I don't know. If you choose to run the command again, you will see just a number and the number of seats. So that's pretty awesome. With active model serializers, you can manipulate the data that you throw out from the server in any way you like. You might have sensitive information that you need to filter out, so you just exclude it from the list of attributes. If you want to pass in information on the relationship, then that's totally fine as well. There are a number of possibilities that are baked into this gem. I'm gonna show you one more feature around this gem, and that is the way that active record renders the global aspect of the JSON file. Let me show you what I mean. Let's clear all of this for a second, and let's go to the config folder in which I'll create a new initializer. This initializer, I'll call it active model serializers.rb. And this load, remember, if you're used to rails, it will basically load this file upon booting the application. I'm gonna type in a single line of code that will configure the overall serializer. This single line of code will change the adaptor for the gem, so for every object that needs serializing, it is going to use a different adapter. I'll leave you a link in the description below about this JSON API adapter, but basically this will change the overall formatting of the data. JSON API is a specification that active model serializers decided to incorporate. To reach a certain point, a certain standard on delivering data, so that multiple applications and frameworks can take advantage of it. Now as for the implications of this line of code, we need to start the server again. So let's just clear the screen, run the server again, and this time, you will see a remarkable change. If I type in this command again, you will see something that's very peculiar. You have this data key first that has the array of all of the stuff. Then you have this type and list of attributes, and also relationships. Check that out. So the relationships for this particular object of type orders has a table which is an object of its own. This object, as well, since it has its own active model serializer, it also respects the specification for JSON API. It has the data, the type, and the remaining attributes. So, in regards to this adapter, there are many others. You can check them out at the link on active model serializers. There's a section on the readme, on GitHub, that specifies, maybe more than a couple of alternatives. One of them is actually the JSON adapter, which basically includes a root, instead of all this specification. Let me just test this out just for you. So I'm gonna reboot the server, and I'm gonna run the same command again. Now, the big difference between this one and the other, let me just clear the screen first. So I'm just gonna type a clear command before writing the request. So, as you can see here, we have orders first and then the table, and everything else is just inside each different order. So this JSON adapter just includes the root so that you can have a more nested kind of content, but not as thorough and exhaustive as JSON API. Don't get me wrong. JSON API is really good because it sets a standard on communication between back end and front end. It's just a different way of rendering results. So, there you go. There's active model serializers. You have a great deal of customization to do. I mean, there's a load of possibilities on how to interact with this serializer. Check the readme on GitHub that I posted in the description below.