without enums:
https://github.com/corsego/50-rails-enums/commit/c8d725750760884216c429d10c5edcb815ccd5b9
enums as integers:
https://github.com/corsego/50-rails-enums/commit/4ca2195316931eac1cfae8b12ebd1d91ddc83ce3
enums as strings:
https://github.com/corsego/50-rails-enums/commit/496c143c2c00945aa9beab0a8054fb1540ffecfb
official guide:
https://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html
#50 ActiveRecord Enum - when and why to use enums?
24/08/2021
Transcript
Hello. So in this episode we are going to go through how and when to use ANUMs in the rub rails application. But to really understand when we need to use them, they're going to first try to build a feature without using ANUMs. So here we have a real life scenario, we have Boths and each post has a title and content. But what if a post should also have a status like banned or draft or published or whatever. So we would need to add the status to our database table inside our post. So let's say rails generate migration, add status to post status would be a stream. And actually we would go to the migration would also say that it should be by default a draft. And now we can run the migration rails to be migrate and start the server. Okay, now we can actually display the post status somewhere. So let's go to our posts in our views, we'll go to views, posts, index and uh, display the post, do status here and here. Okay. And you see by default it is set to be draft. And if you create a new post, we would also want to be able to input the status. So they're going to our posts form, they're going to add one more field. It would be, for example, a text field For status. Let's have a look. So by default it is trough and we would want to be able to change it. So we'll go to our controller, post controller and add it to the strong brands like this. Okay. Now we can change the status. Let's go to one of the existing posts and change it from draft to draft one and update the post. And it looks like it felt, you see it was changed to draft one. Okay. But we don't want be able to just write in the status. We want to have a collection of statuses. So we will go to our post form and we would say not form text field. We would say form.select status. And the options are going to be draft and let's say published. Okay, Going back, you see we have a select field and we can set it to be published. Now, let's go back and you see it was set to published, but we can still go and, uh, change it to something different. Let's say I will go to the HTML and change the selected one to be published. 1, 2, 3, 4, 5. And now press update, post and go into posts. We see that the status is published 1, 2, 3, 4, 5. So this way we kind of hacked our application. We changed the status, though it wasn't available inside our form. So we should add some validations and we should actually not keep our collection inside our view. We should keep it somewhere in our model. So let's go to our models post RB and uh, the, and here we will say, uh, statuses equals uh, uh, draft published and let's say banned. Okay? And inside the form we will say that the available statuses, statuses are going to be post statuses. Let's see if it works. So here we have three different statuses. Let's change it to band, update the post, go back to posts. And it seems to be working, but we would definitely want to add the, some validation of inclusion. So we would say validate Status, inclusion to be in post statuses. And now it should, uh, possibly work. Let's just try once again, I'm going to go and edit. Let's see if I still can access the available values. So going to the select, I will change the value to be banned. One to three, go to update the post. And uh, okay, Yeah, I had a typo with letter E. Let's try once again, I will resend. So resubmit the form. And you see we have, this status is not included in the list. So our validation of, uh, inclusion seems to be working and everything will be fine. But what we want to see all the posts that have a status of, uh, draft, for example, well, let's say, I'll say rails console and say post dot draft, and we don't have a collection. So let's create a scope. We would create a scope to see all the posts that have the status draft. So we would say scope, draft lambda there, status equals draft and close this gap. And let's see, once again, I will restart the rails console and if a type post draft would get an array of all the draft posts, but we don't have any at the moment. So we would also maybe want to have the same kind of scopes for published and banned. So we'll have scope published and scope band, and now go into the console. We can say post band and post published. So this kind of works, but what if you want to check if a specific post is banned or published over whatever. What if you say post do first dot banned, we get no method error. So would need to create a method for this, let's say would create a method dev band. And we would say, uh, status equals band. So it would give us a true or a false. And now if we say rails console and search for post first band, you see we get true. And if we check for post first, uh, uh, draft, we get no method error. So we would need to create the same methods for draft and for published. And you see this is quite a lot of code. And uh, instead of writing all the code, you can just use ribbon rails anonymous. So let's see how they work. Now. First I'm going to just save all the changes that we just did. Get status, get, add all, get commit main, and I'll say without Anos. Okay? And now we're going to actually try to use anos. So they're going to remove all of this. And, uh, going back to our migration. So by default, what are anos? You would, uh, have an integer saved in your database and you would have a few different, uh, kind of statuses or array of, uh, anything that you want in your database that can be, uh, searched as by a method and uh, with a scope. So whatever you have in an A norm can be searched for, uh, with a method and a scope. So you don't need to write, uh, all the code for scopes for methods. You don't need to write this validation. All this is included automatically. So this is really handy. Let's try and see how it works. Now, by default, you would want to use, uh, an num with an integer. Now, what is the trigger thing? You kind of have a list of strings, but they are persisted in the database as integers. Let's just see how it works. I will, uh, first of all, uh, run a rails, the be rolled back, okay? And now I will say at column post status integer, now rails, the be migrate, and I'm going to add an A number of statuses. Now, the latest, uh, edge guides of Rubion rails at the moment, uh, uh, say that this should be the correct syntax, but I'm using rails 6.1 0.4, and you see the synex is slightly, slightly different. So I would say something like ano, okay, let's just copy it. Ano status, uh, draft and published. Okay, so we have two statuses and let's, uh, slide them in our form. So I'll go to the rail server. And you see previously we had both statuses, and now we'll want to have, uh, it slightly differently. We want to have the ones that are in the anon. So going to edit, we must have an error that there are no post statuses like that. We would just say post statuses. Let's see if it works. Yeah, so we have JT and published, let's save this post as, uh, published. I'll press update post. And you see it gives us one is not valid status. Now where do we have this error from? Basically, these are saved as integer in the database, but we have them as strings in inside our model. So here is something I will, uh, open and separate fin the the rails console and say post statuses. And you see we have a hash of keys and values. So I can say post statuses, keys and do values. So seeing the draft has the value that'll be set in the database as zero. It is like the index and publish would have a one. And if it had something like, uh, band, it would have the index of two. So zero one tool. And we are trying to send one, but not, uh, a but not a key. So we're trying to set the value, but not the key inside our form. So here we would say post statuses, keys in the collection. Let's go back to edit once again. And here you see again, we have the same keys. Nothing has changed. So I'll just say post, uh, status band or whatever, and update the post. And it seems to be working. So you see the status is banned. Now what if, uh, I add another status. Let's say I'll add a status as, uh, in review, I added the status. And now look attentively. I'm refreshing the page. And you see the status has changed. Now why has it changed? Because the index has changed. So we try to find, uh, an element with the index of, uh, 0 1, 2 of two inside our view. And the two is published. So you see, you shouldn't add anything new on the beginning of the string. You should add this, uh, I review or whatever you want in the end of this, uh, anon. And then it's not going to break, uh, your lineup. So this is not kind of really nice. I don't like the idea of, uh, having to have a specific order of, uh, values here. And I don't like the idea of, uh, them being mapped, uh, just, uh, to specific inte, like 0, 1, 2, 3, 4, 5. So instead we can use something different. We can say, uh, draft is, uh, zero. Published is one band is 13 in review is 534. And now let's try once again, I'm going to refresh and we get the must be other hash an array. Okay, I'll try it like this and it should work. So I'm going back and I'm going to edit this And I'll change the status to in review, update post. And it seems to be broken. So going to post both you see is in review. And if we remove a norm, let's say, we'll comment it out, the database value should be 534. Let's see. And it did is is 534. And let's play a bit more. So let's, uh, create one more post and try to do some scopes and some kind of methods. So second post, it should be a draft, okay? Or let's make it published some content and create post. And let's go back to our rails console. I will restart it now, exit and rails console. And let's see, post dot count. We have two posts. Let's say post band, we don't have any, let's say post published. We have one post that is published. Now, let's say post fer published. And you see we have this method. So it give us a true or false, let's say post second published. It is true. And let's actually make the first post published, we'll just say published, but with an exclamation mark. And you see we've updated it to be published. So, so let's say post published Dot count. And now we have all the posts, all of them should be published. So we see if we can do a lot of, uh, different stuff using nus. We can check if a specific post is, uh, published. We can, uh, check, uh, uh, we can force it to become, uh, uh, of a specific status. We can, uh, have all our, uh, scopes by default. And uh, it's really cool, but, uh, I still don't like it a lot. So you see here have, uh, this na status and the hot code in the strings to integer. It's, it's not really cool in my opinion, but if they use, uh, uh, encoding strings to strings, that would make, uh, kind of a bit more sense. So, uh, let's try that. Let's just change, uh, our, uh, save our changes get at all. Oh, nevermind. Let's, uh, say we will roll back rails, DB roll back. And once again, the status is going to be not an integer, but a stream. So status would be stream, okay, rails db, migrate. Okay, we've migrated and they're going to encode draft to draft published to published, banned to banned and all we don't need in review anymore. And let's see if, uh, it works. So I'm going to refresh the page. Now the status should be blank because we've done a rollback and let's try to edit will it work? So let's go and change the status to published and update the post and going to edit. Will it be published? Yes, it is published. So looks fine. Let's make it band. And going back to edit. Yeah. So it was changed to band and it should be also saved correctly inside our database. So even if they remove the ano on The status should still be set to band. So this kind of, uh, is a bit more human readable, okay? And the more thing, what if they want to have some default values? Now in the previous sales versions, you would, uh, just set the default value inside your database on the database level. But what if you want to change the default value later on, you don't. You would have to run some kind of migrations. And now you can actually set default values inside the anon. So actually the synex is quite different in the rail. 6 1 4 here is the synex for setting default. And in the edge guys, it's also already different. It's slightly improved. So I'm using 6 1 4 now. So I will say, uh, default it would be, uh, let's say band for example. And let's create a new post. And you see, by default it'll set the band, let's make it published B by default. And now it is published by default. Okay, so looks fine. And actually we can also access this default value inside our console. It will just need to say something like, uh, post new status, and here we have this value, let's change it from published to draft And post new status would be, okay, I would need to restart the console and now post new status would be dropped. So it kind of works and we can access, uh, that default value through the console. And now let's see if it works inside our form. So I will, uh, restart the server. Okay, not the console, but the server rails s okay. And now going to our posts. So here have, uh, in your post status is trout by default. Let's see if it also works. If we have in include blank, let's say include blank would be true. So let's go to post to new post. So by default it is draft, even if they include blank. And let's create it. So let's make it, uh, published, create post. And if we go back, it is saved as published. So everything works file. Okay, and just a few things that you might need in the future. For example, if you have two omes that have, uh, something similar, so let's say you would have a non, uh, state and that would also be an option of being published. Well, then you would be able to use something like, uh, prefixes and subes. And you can also disable scopes for different anos. So you see, you can disable a scope to be false. And uh, you can also, uh, here are the su fixes and pres. So you can add a Sufi to be active status or whatever. And similarly with pres, well, and this is basically it. So the most important things about Enos that you can use them as saving in the database as strings as an in also with intes or strings. Yeah. And uh, I usually prefer strings because it's slightly more human readable than it is better to set the defaults on the modal level, but not on the database level. And, uh, well that's basically it. So the cool thing is also that you can run all the scopes and all the presence methods, uh, by default and you don't have to write the, a lot of extra code. So that's it, and I hope you liked that episode. Goodbye.
0