Ruby on Rails #50 ActiveRecord::Enum - when and why to use enums?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello so in this episode we are going to go through how and when to use anoms in the ruby on rails application but to really understand then we need to use them we are going to first try to build a feature without using a norms so here we have a real life scenario we have posts 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 posts so let's say rails generate migration add status to posts status would be a string and actually we would go to the migration would also say that it should be by default add draft and now we can run the migration rails db 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 display the post.status here and here okay and see by default it is set to be draft and if we create a new post we would also want to be able to input the status so we're going to our posts form we'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 draft 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 params 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 phone and update the post and it looks like it worked you see it was changed to draft phone okay but we don't want to 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 dropped 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 change it to something different let's say i will go to the html and change the selected one to be published one two three four five and now press update post and go into posts we see that the status is published under through five 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 pose.rb and [Music] and here we will say statuses equals draft published and let's say band 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 validates status inclusion to be in [Music] post statuses and now it should 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 i'm going to the select i will change the value to be band 103 go to update the post and 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 inclusion seems to be working and everything will be fine but what we want to see all the posts that have a status of 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 it would create a scope to see all the posts that have the status shaft so let's say scope draft lambda var status equals draft and close this gap and let's see once again i will restart the rails console and if they type pose job would get an array of all the draft codes 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 the scope band and now going to the console we can say post dot band and post dot published so this kind of works but what if you want to check if a specific post is banned or published or whatever what if we say post dot first dot band we get no method error so we need to create a method for this let's say it would create a method def band and we would say 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 draft we get no method error so we need to create the same methods for draft and for publish and see this is quite a lot of code and instead of writing all this code you can just use ruby on rails enormous so let's see how they work now first i'm going to just save all the changes that we just did get status kit add all git commit main and i'll say without enormous okay and now we're going to actually try to use enough so we're going to remove all of this and going back to our migration so by default what are enums you would have an integer saved in your database and you would have a few different uh kind of statuses or array of anything that you want in your database that can be uh searched as by a method and with a scope so whatever you have in an om can be searched for with a method and a scope so you don't need to write 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 an enum 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 first of all run a rails db roll back okay and now i will say add column post status integer and now rails dbm migrate [Music] and i'm going to add an a number of statuses now the latest the age guides of ruby on rails at the moment say that this should be the correct syntax but i'm using rails 6.1.4 and you see the syntax is slightly slightly different so i would say something like a normal okay let's just copy it and i'm status draft and published okay so we have two statuses and let's uh select them in our form so i'll go to the rail server and you see previously had both statuses and now we'll want to have it slightly differently we want to have the ones that are in the enum so going to edit we must have an error that there are no post statuses like that we would just say post dot statuses let's see if it works yeah so we have dropped and published let's save this post as published i'll press update post and you see it gives us one is notability status now where do you have this error from basically these are saved as integers in the database but we have them as strings inside our model so here is something i will open in separate window the rails console and say post dot statuses and you see we have a hash of keys and values so i can say post statuses dot keys and dot values so you see the draft has the value that will be set in the database as zero it is like the index and publish would have a one and if we had something like band it would have the index of two so zero one two and we are trying to send one [Music] but not uh 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 dot 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 status.band or whatever and update the post and it seems to be working so you see the status is banned now what if 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 the an element with the index of 0 1 2 of 2 inside our view and the 2 is published so you see you shouldn't add anything new on the beginning of the string you should add this interview or whatever you want in the end of this uh anom and then it's not going to break your lineup so this is not kind of really nice i don't like the idea of having to have a specific order of values here and i don't like the idea of them being mapped just to specific integers like zero one two three four five so instead we can use something different we can say draft is zero published is von 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 either hash and 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 interview update post and it seems to be working so go into posts you see it 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 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 to post let's say post dot band if you don't have any let's say post.published we have one post that is published now let's say post doctor first dot published and you see we have this method so it will give us a true or false let's say pose dot second not published it is true and let's actually make the first post published we will just say published but with an exclamation mark and you see we've updated it to be published so let's say post dot published dot count and now we have all the posts all of them should be published so you see we can do a lot of different stuff using the numbers we can check if a specific post is published we can check we can force it to become of a specific status we can have all our scopes by default and uh it's really cool but i still don't like it a lot so you see here we have this num status and the hard code in the strings two integers it's it's not really cool in my opinion but if we use uh encoding strings two strings that would make kind of a bit more sense so uh let's try that let's just change our save our changes get at all oh never mind let's say we will roll back rails db roll back and once again the status is going to be not an integer but a string so status would be string okay rails db migrate okay we've migrated and we're going to encode draft to draft published to published band band and all we don't need in review anymore and let's see if it works so i'm going to refresh the page now the status should be blank because we've done a roll back and let's try to edit will it work so let's go and change the status to published and update the post and go into edit will be published yes it is published so looks fine let's make it banned 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 we remove the nom the status should still be set to bend so this kind of is a bit more human readable okay and one more thing what if we want to have some default values now in the previous rails versions you would 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 nom so actually the syntax is quite different in the rail614 here is the syntax for setting default and in the edge guys it's also already different it's slightly improved so i'm using 614 now so i will say default [Music] it would be let's say band for example and let's create a new post and you see by default it was set to banned let's make it published to be 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 we will just need to say something like post dot new dot 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 both new status would be draft so it kind of works and we can access the default value through the console and now let's see if it works inside our form so i will restart the server okay not the console but the server rails s okay and now go into our posts so here we have a new post status is trout by default let's see if it also works if we have include blank let's say include blank would be true so let's go to posts to new post so by default it is draft even if we 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 noms that have something similar so let's say you would have a nom state and there would also be an option of being published well then you would be able to use something like prefixes and suffixes and you can also disable scopes for different enums so you can disable a scope to be false and you can also uh here are these suffixes and prefixes so you can add a suffix to be active status or whatever and similarly with prefixes well and this is basically it so the most important things about enormous that you can use them as saving in the database as strings as an also with integers or strings yeah and i usually prefer strings because it is slightly more human readable then it is better to set that defaults on the modal level but not on the database level and 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 a lot of extra code so that's it and i hope you liked the episode goodbye
Info
Channel: SupeRails
Views: 488
Rating: 5 out of 5
Keywords: ruby, rails, ruby on rails, tutorial, programming
Id: Ac8syCb01ys
Channel Id: undefined
Length: 22min 24sec (1344 seconds)
Published: Tue Aug 24 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.