Playing Next Lesson In
seconds

Transcript

  1. Now the fun begins. Let's go ahead and create a page inside of our application that lists all Cineasts who have directed any movies. Then from there, we'll create a show page for that director,

  2. listing all of the movies that they've directed. Let's hit "Command P" and type in routes to jump into our routes file. Underneath our movie show page, let's go ahead and add in an additional page.

  3. So router.get/, we'll call this directors. Then if we stop and take a look at our controllers, we don't have a controller applicable for this.

  4. So let's dive into our terminal and let's run node, ace, make, controller, directors. Then we'll also want to stop it with a method called index.

  5. So add index there to the end of this command. Let's run that. There we go. So now we have a director's controller with an index method stopped inside of it. So we can type out director's controller,

  6. hit tab to auto-import that just like so. Once we save that, we'll switch to the correct lazy import here, and we'll use the index method there since this will be

  7. our listing page that will list all directors that we have. So we'll call this as directors.index. Once we save, we saw this switch from an orange tint

  8. to a purple tint indicating that it did switch to a lazy import. We'll hold option down to switch that to down below our router import there to keep all of our controller imports together.

  9. Jump over to our director's controller, and there is our stubbed index method. Out of our HTTP context, let's grab our view, and let's go and just start by returning view,

  10. render pages/directors/show. Let's create that page real quick. Let's also go ahead and delete out the movies that we have inside of our resources movies directory.

  11. So we'll hit delete there, move that to the trash. Let's go ahead and right-click that, new file, add a folder called directors/, and whoops, we're still on the index method,

  12. so we'll want that to be called index, not show. My bad there. So index.edge. Let's jump back into our director's controller and fix that real quick. So instead of show, we do want this to be called index. Okay, there we go.

  13. So we'll do @layout, @ender layout, and we'll just do an h1 of directors so that we have something listing out this page. Let's go ahead and dive into our partials

  14. for our navigation, and let's add in an additional anchor, href, pointing to our route, directors.index, and we'll call this directors.

  15. Okay, give that a save. We should now be able to jump into our terminal and pm run dev to boot up our server. Let's open up our browser. Okay, here's our homepage. If we click into directors now,

  16. we get an h1 with directors. Awesome. Let's hide that back away, jump back into our text editor, and let's go back to our director's controller.

  17. We'll do const directors equals await. We'll want to query from our Cynist model, so we'll import that. We're going to want to use the Cynist models query builder.

  18. Now, we're going to want to query all Cineasts who have a movie where they are the director ID. So we're going to want to use, if we dive into our Cynist model,

  19. the movie's directed relationship to check and see whether or not they have any records. So for that, we could do where has

  20. to check the existence of a relationship. Whenever we hit the strings, we get IntelliSense popping up that we have movies directed available to us. If we needed to, we could provide a callback function

  21. as the second argument here to extend the movies directed query to add additional statements to those movies. For example, if the Cynist has only directed movies that aren't out yet,

  22. maybe we don't want to include them in this list. So we could go ahead and apply a query scope to our movies directed relationship from our movies query,

  23. and this will be our movies query builder here. So we have access to our scope.releasedQueryScope. Now, if we hit "Save", the red squiggly is just due to formatting.

  24. So there we go. Now, we should have directors who have directed any movie that's already been released. So we can provide that into our directors index as directors.

  25. Let's dive back into that page. For now, let's just do a ul, each to loop over them, director in directors at end are each,

  26. and then we'll do an align here with our director full name. Give that a save and let's go check it out to see if everything worked. Jump back into our browser, and there we go.

  27. Now, at this point, it's a little bit of a random list. We don't have any sorting going on. So let's fix that real quick. Hide that back away, jump back into our directors controller,

  28. and to the end of our query here, we can add on a dot order by, and we don't want to order by two columns, the first name and then the last name.

  29. We cannot order by a computed property because it does not actually exist inside of the database. So we can provide an array into this, and in the first index,

  30. we specify the column that we first want to order by, which would be our first name. The default direction is going to be ascending, but if we need to change that or if we want to explicitly set it,

  31. we can set it to order by ascending. Then we can add in a second index here, where the second column that we want to order by is last name with the order of ascending there as well.

  32. Give that a save. So we'll first order by our first name, and then once it's done ordering by first name, if we have any Sinus record using the same first name, they'll then be ordered by the last name.

  33. Cool. So let's jump back into our browser, give that a refresh, and there we go. So now they are listed in alphabetical order. Now we need to be able to click into them and show

  34. a details page with the movies that they have directed, listed out. So I'll hide this back away. So let's scroll down a little bit here, and let's do a public show page. We'll grab view out of that,

  35. as well as our params, HTTP context, and we'll go ahead and return view, render pages, directors, show.

  36. Before we go any further, let's define the route for this. So we'll dive back into our routes. Underneath our directors route, we'll do router.get directors/,

  37. and we don't have a slug for our directors, and it's possible that directors could have the same first name and last name. So for right now, we'll just need to do ID there,

  38. and we can use the director's controller and specify the show method there is directors show. Let's round out our circle by diving back into our directors index page,

  39. and let's add a link around our full name here. So we'll do a href route directors show,

  40. and let's add the param ID of director.ID. We'll end our anchor and move that end tag down below our director full name.

  41. Then we'll need to create our show page. So I'm just going to copy everything that we have here because it's going to be relatively similar, and we can right-click our directors page,

  42. new file, show.edge, paste that in. Instead of directors up here, this will instead be director. Then we can list out their full name.

  43. Then for our loop, let's just jump back into our homepage, and let's copy our div where we're using our cards, jump back into our director show page, highlight this, give that a paste,

  44. and we can get rid of our URL. Cool. Now, instead of coming soon, this will just be all of their movies like so. So we give that a save, and let's jump into our movie card as well

  45. because we're still using PIXM here, but we have actual poster URLs tied to our movie now. So we can replace that PIXM poster URL there as well.

  46. Close that out because we're done with it. Jump back into our director's controller, and let's add in the query to get our director from our ID parameter and their directed movies.

  47. So const director equals await cinist.findOrFailRams.id.

  48. So we'll find or fail our cinist by their primary key ID column provided into our route parameter ID value. This also needs to be an async method.

  49. There we go. So we can go ahead and add in our director into our state for our page, and now we need to get their movies. So we can do await,

  50. and for this, we can reach through this director to get their related movies via its relationship.

  51. So we can do director.related to reach through a relationship, and we specifically want to use the movie's directed relationship here,

  52. .query to get that relationship's query builder. So now this is a movie query builder using the relationship bound to this specific director.

  53. So let's go ahead and order by that movie's title, okay? And let's add the movies into our page state there as well. We'll give that a save.

  54. Let's jump into our browser and see if we got everything right. So these are actual links. They aren't shown like that because of the TailwindCSS reset, but let's go ahead and click into Clark Strosen

  55. because we were working with him in our last lesson. So we know that he is bound to 310 to Yuma. So we can click on him, and look at that. His very first movie is 310 to Yuma.

  56. And now we have all of Clark Strosen's directed movies listed out on his page. Awesome. We'll add director to the start of the name just so that we have that explicit.

  57. So let's jump back into our show page here, and let's do director, full name. Okay, so now that should be director Clark Strosen. There we go. Awesome.

  58. So if we go back to our director's page, let's click on somebody else. There's another handful of movies. Click on somebody else, another handful of movies, and let's click on somebody else.

  59. And this person only has one, so they are one of the ones that we created using the with method with our movie factory. So cool. Everything seems to work.

  60. And even furthermore, we can click in to see the movie's details page from each one of those.

Listing A Director's Movies with Relationship Existence Queries

@tomgobich
Published by
@tomgobich
In This Lesson

We'll learn how we can perform a relationship existence check to grab a list of our cineasts who have directed one or more movies. We'll then create a show page for that director, listing the movies that they directed.

Join the Discussion 4 comments

Create a free account to join in on the discussion
  1. @nico75

    Hey, first, thanks for this full tutorial.

    I try to use route with a custom button component

    Copied!

    @shared.button({href: "{{route('movie.show', {id: movie.slug})}}", class: ""}) View Details @end

    this not work

    @shared.button({href: "movies/" + movie.slug, class: ""}) View Details

    this work

    Is there a way to achieve this ?

    1
    1. Responding to nico75
      @tomgobich

      Hey Nico! Thanks for watching!

      When you're passing props into your button component, you're already inside of an EdgeJS interpolation area. So, at that point you don't need the double-curly braces and adding them will actually mess things up in that context. Instead, you can directly access the route function, like below.

      @shared.button({ href: route('movie.show', { id: movie.slug }), class: "" })
        View Details
      @end
      Copied!

      Also, and this might've just been formatting in the comment, but just in case also be sure the start and end tags for your EdgeJS components are on their own lines.

      1
      1. Responding to tomgobich
        @nico75

        Thanks a lot. It work now.

        I'm going to continue to watch the videos, very helpfull to learn Adonis and Edge !

        1
        1. Responding to nico75
          @tomgobich

          You're welcome, Nico! Happy to hear all is working now!

          Hope you enjoy your time with AdonisJS & Edge! 😊

          1