Playing Next Lesson In
seconds

Transcript

  1. So as we defined in our last lesson, we're going to want roles and movie statuses to exist before anything else inside of our database.

  2. Additionally, we're also going to have specific values for those two tables as well. We're gonna have specific roles inside of our application, and we're also gonna have specific statuses that a movie can have.

  3. And the approach that we took to create records in the last lesson by jumping into a REPL session and creating them that way, isn't a scalable way if you're working with a team. If you're a single person working on an application,

  4. that's fine, but if you have other members of your team that's going to need to spin up a same instance of your database and get populated quickly with that same information, that's where CEDARS come into play.

  5. CEDARS allow you to define that information that you're gonna need inside of your application. You can run the CEDAR to create that information automatically, so that you don't have to have somebody jump into a REPL session,

  6. create that information themselves. They can just run the CEDAR and it will be automatically created for them. So within our terminal, let's go ahead and create a new CEDAR. First, let's do node.ace_list to see our available options.

  7. We're gonna be making something, so we'll look underneath the make section and sure enough, there's a make CEDAR. Node.ace_make_cedar. Now, how you define your CEDARS is completely up to you.

  8. You can either have a single CEDAR that's going to make everything that you need to get started with your application, or you can divide individual CEDARS per resource that you're gonna have

  9. that you need to create information for. So for example, we could create a single CEDAR for our roles and a single CEDAR for our movie statuses, or we could create a single CEDAR

  10. to create both of those informations for us. Since we're just getting started here, let's just focus on a single CEDAR. So let's just make a start CEDAR. Okay, there we go.

  11. So now we have a new CEDAR file at databases/cedars/start_cedar. We can go ahead and jump into our text editor and jump into our database directory, CEDARS,

  12. and there's our start CEDAR. You'll see that it's exporting a default class that extends a base CEDAR. The base CEDAR is going to provide the functionality to actually allow us to execute this,

  13. and then it's providing an async run method where we can create our movie statuses and our roles, and we can use our models for both of these. And we can do so similarly to how we did in the REPL session.

  14. So we can await, import our role from our role model, dot. We have a create method that we can call, and we just need to pass the values in. So we could do name, administrator,

  15. so on and so forth as we did in the REPL session, but additionally, there's also a create many option as well where we can pass in an array of those objects. So if we had two roles to make,

  16. we could pass in two objects to create them, which matches exactly what we have. So let's go ahead and do this. So we could do name, user, and name, administrator,

  17. or let's just do admin 'cause I find it rather hard to type out administrator for some reason. There we go, give that a save. And if you'll recall back inside of our user migration,

  18. so let's dive into our migrations there and click on our users one, we gave our roles for our users a default value of one, which essentially, if we jump over to our start CEDAR,

  19. is going to be the user role. If we wanted something to fail whenever we try to create our base CEDAR, if one cannot be assigned to the user role,

  20. we could explicitly assign the ID here to cause that failure to happen. Remember, whenever we inserted using the create method, the ID was automatically assigned for us.

  21. We didn't have to manually assign it. So you do not have to manually assign this. If there are instances though, where you want this to fail, if it cannot be assigned a specific ID,

  22. that's where you can explicitly assign the ID. And since our user default value is dependent on one being there, we'll go ahead and do that here.

  23. So we can explicitly assign our user role as one and our admin role as two. So let's pause here and take a look at exactly that,

  24. because we already have a user role with an ID of one. So we will expect this to actually fail. So let's jump into our terminal. Let's go ahead and clear things out. Actually, before we do that,

  25. let's scroll up a little bit so that we can see the command. And this is going to be underneath the DB section. We have dbced. And by default, this will execute all CEDARs within our application.

  26. If we take a look at the help method for that, we can run specific CEDARs. So node.ace.dbced-help. There we go. You could specify individual files that you want to run

  27. for a specific CEDAR file. If there's just one particular one that you want to run, you can do that. There's also an interactive mode. And if you have separate connections, you could specify the connection as well. Okay, cool.

  28. So let's go and clear that out. Let's do node.ace.dbced. Again, expecting this to fail. And there we go. So it failed with our start CEDAR,

  29. and it was trying to insert roles with the column specified with the values, returning ID, and the specific reason for the failure is a duplicate key violates unique constraint

  30. for that primary key ID. I.e. it could not assign the ID of one to our user here whenever it tried to create it. If we were to get rid of that ID, give this a save.

  31. Let's jump back into our terminal, and let's run node.ace.dbced once more. Everything should work, which indeed it did. It completed our CEDAR.

  32. But if we jump into pgadmin once more and hit play to run this query again, you'll see that these two bottom records are the ones that were created from our CEDAR,

  33. and they were assigned an ID of three and four, skipping two because two was deleted already. So if we did not have this first record here, we would only have roles with an ID of three and four

  34. within our database. So that's where that explicitly assigning a value inside of your CEDAR may come in handy. But for the most part, you should be able to ignore assigning IDs onto information

  35. because the database will take care of that automatically for you. So since we're explicitly expecting our role and our admin to have IDs one and two,

  36. we can define this additionally using an enum. So within our app directory, let's create a new folder. So we'll do new file here. We'll call the folder enums, and we'll call the file roles.

  37. We can hit enter there, and let's define an enum called roles. Let's do our curly braces, and let's define our user is going to equal one, and our admin will equal two.

  38. Let's go ahead and export default our roles. Essentially what this will allow us to do is, let's say we want to check whether or not somebody is an admin. Well, now we have an explicit reference

  39. to what role inside of our application specifies who's an admin. So let's assume that we have a user variable here.

  40. We could do user.roleID equals roles.admin to discern if somebody is specifically an admin inside of our application.

  41. So now that we have that, we can jump into our CEDAR, and we can assign the IDs using the enum. So we can do roles. Let's import that from our enums directory, and let's actually scroll up a little bit.

  42. So that did a relative import. Let's go ahead and add a subpath import for our enums directory. So we can scroll down to our package.json. We'll do this just above exceptions.

  43. So we'll do #enums/*://appenums*.js. Give that a save. We can go ahead and give that a copy as well.

  44. Let's dive down to our tsconfig, and we'll do the exact same thing within here. So we'll give that a paste, and just wrap the value inside of an array. Cool. So now we can give that a save,

  45. jump back into our start CEDAR, and switch this to a subpath import. So we can do #enums and get rid of the extension. Okay, cool.

  46. So let's dive back down to our role creation here, and finish out our thoughts. So roles. And let's assign the ID here for our user as user,

  47. and for our admin as roles.admin. We can do the exact same thing within our users migration. So if we go back to that file, let's dive into our database,

  48. migrations user, scroll over to where we have that hard one, and let's do roles, import that from our enums roles. And let's assign them the user role.

  49. So not only does this make things easier to read, we now know just by simply looking at it, that our default role for our users is going to be the user role, but we also have a safeguard throughout our application

  50. via our start CEDAR, that we know explicitly that the user role is going to have an ID of one, otherwise it's going to fail to create, and the same for our admin with the ID of two.

  51. Okay, next we need to do the exact same thing for our movie statuses. So let's go ahead and jump back up, and let's define an enum for that first, so that we have that same safeguard going on for those.

  52. So do movie_statuses.ts, enum movie_statuses, and let's do writing equals one,

  53. casting equals two, production equals three, we'll have post production as four, and then finally released as five.

  54. And let's export default movie_statuses just like so. So now we have a hard definition on what status represents the movie as being written,

  55. movie as being casted, cast members, the movie is being produced, so actually going through filming, post production and released.

  56. Let's jump into our CEDAR and actually get those created. So I'm just going to condense down our role create many here, and we can do await movie_status, import our model for that,

  57. dot create many, our array, and we'll do objects for these. Scroll down slightly here, ID, movie_statuses, there we go, import that enum, dot,

  58. and we'll go in the same order as our IDs, so we'll do writing first, writing ID, movie_statuses, dot casting, name, casting, scroll down a little bit more,

  59. ID, movie_statuses, dot production, name, production, and we have post production, so movie post production there.

  60. Okay, and then lastly we have released, so ID, I've just kind of given up on writing movie_statuses, and I'm just kind of fusing. Auto-complete there to round it out for me there,

  61. and then we'll do released for that value there, and name released. Okay, cool. Give that a save, everything should get their auto-commas added in,

  62. and now we should be good to go. So first, before we actually run this, if we dive back into pgAdmin here, we're going to want to clear out the roles that we already have defined inside of this table,

  63. and reset the IDs for this table as well. So let's hide pgAdmin back away, because we can't just simply delete them, as that won't reset the IDs,

  64. which use sequences to keep track of what ID is next in the sequence. So we can jump back into our terminal here, hide our text editor back away, clear this out,

  65. and let's use our node.ace.list to list out our available commands, and we have our migration commands here at our disposal to do this for us.

  66. So first, let's try refresh. Essentially, that's going to roll back, so we'll run the rollback command, and then we'll run our migration. So we'll run the run command, essentially,

  67. automatically within that single command. So we'll do node.ace.migration.refresh, hit Enter there. Okay, that reverted all of our migrations and re-migrated them.

  68. So if we dive back into pgAdmin and hit Run, we no longer have any information inside of our database, so we can hide that back away, and let's try node.ace.db.seed.

  69. And there we go, everything worked A-okay. Let's jump back into pgAdmin, hit Run once more. Okay, so I'm not quite sure what's going on with pgAdmin there. Let's go into View, All Rows again.

  70. Oh, we probably just need to refresh everything since we've re-migrated it. So let's jump back up to our database, right-click on that, and hit Refresh. Okay, scroll back down,

  71. and let's try again on our rules table. So let's right-click that, View, Edit, All Rows. There we go, okay. So we just needed to refresh pgAdmin here to let it know because it was trying to reference the old tables

  72. that no longer existed. So we just needed to give it a refresh there. Okay, cool. So we have our user record with one and our admin record with two, and we can jump into our movie statuses.

  73. So right-click there, View, Edit, All Rows, and we have all five of those here as well with writing, casting, production, post-production,

  74. and released, all with their explicit IDs that we expect. Awesome, so everything's working there. And since we created these using our Lucent models, our createdAt and updatedAt

  75. were automatically added in for us. Awesome.

Defining Required Data with Seeders

@tomgobich
Published by
@tomgobich
In This Lesson

Our database will have specific, non-changing, roles and movie statuses. In this lesson, we'll learn how we can quickly and easily create these records inside of our database using seeders.

Join the Discussion 2 comments

Create a free account to join in on the discussion
  1. Copy/pasting your own remark here from lesson 2.17:

    As of TypeScript 5.4, TypeScript will read and use subpath imports directly from our package.json, meaning we no longer need to redefine them inside our tsconfig.json file.
    As such, AdonisJS has now removed these definitions from the tsconfig.json file by default and you only need to define them inside your package.json file.

    1
    1. Responding to thomas-de-groof
      @tomgobich

      Thank you, Thomas!

      1