[MUSIC] In this lecture, as a part of implementing the ThingImage resource, we will discuss Nested Resources and Nested Resource URIs. Exposing the same controller action from multiple URI viewpoints. What can we do when our parameters shift from the URI to the payload, or from the payload to the URI. We're going to leverage the query scopes put in place, and you'll see how those custom compound responses are going to be very useful in the API. And then of course, as we build our resource, we're going to bake in the authentication policy. Okay, to go further with ThingImage, what we're going to do is use the resource scaffold generator. And we're going to create a ThingImage controller with an index, create, update, and destroy method. And then this skip says, if anything already exists, skip it. Don't ask me any questions. And you'll notice that it skipped over the migration, the model class, the model spec, and the factory. And it went on to create the controller and the resource, and I'm not sure why but it doesn't create the views, we'll have to do some of the stuff manually. If we go into the routes file we notice that thing_images is at the root, we want to remove it and move it into the API, except it's unique. We're not going to refer to ThingImages globally, we're going to refer to them scoped either below things or images, and we'll start out referring to them under things. All right, when we specify the resources below things, what I'd like to do is only expose index, create, update, and destroy. That's almost the same of what we've said here except we're not including show. So I probably could have added except show, but I chose to do it this way. And then, although it's through things that we're going to manage ThingImages, like deleting them and editing them, it's going to be through images that we're also going to be able to create them, and get them. It'll make for a fairly consistent interface if we do it this way. What ends up happening is the create method that gets mapped to a post, that gets mapped to a create method in the thing_images controller will also have that same method exposed under images. So, we can link from things to images and images to things. And we can get our links through our images and we can get our links through our things. However, depending on what perspective we come from, we're going to want to see the information differently. And then just to make sure that we've got some decent functionality in place, I'm going to add this additional method, where we're going to get not only what are we linked to, but we can also get what could we be linked to. If you remember that one query scope of not linked, this would be a URI that gets us to the result of that query scope. So primary management of thing_images is under things, selective methods of thing_images is below images. And if we run rake routes and I've gotta scale it down a bit, that if we're getting to thing_images through image, it's image_thing_image and if we're getting through thing_images through things, it's things_thing_images. As ugly as the shorthand naming is to say thing twice, it actually ends up being more sane in the end because we have two ways of getting to it and it's very clear when you see, we're coming from the image side of things or we're coming from the thing side of things. And these are helper methods that are only exposed inside of Rails and probably the most that you'll ever see of them is in our specs. But you'll notice that when we come into the thing_images, when we come from the image side the image_id is in the URI. And when we come from the thing side of the house, the thing_id is in the URI. So if we're ever going to create a link through images, then thing_id is in the payload and image_id is in the URI. If we're ever going to create a thing_id from the thing side, then thing ID is in the URI and image_id is in the payload. If we go into the controller, I'm not quite sure why it didn't create the stubs of those methods that I specified, but it's easy enough for us to create them. So one of the things that we want to take care of is wrap_parameters. If a thing image comes in the mail and it has an image_id, thing_id, or priority, we want to copy that down under a thing_image element. And while we're thinking of such things, let's go ahead and create a thing_image_create_params helper method that's specific to create that will require that we have a thing_image document and inside of it have an image_id or thing_id depending on which URI you come in on. So in the wash Rails hides whether we're getting image_id from the body or the URI, and he just says in the params, here it is. So if we can't find image_id at the root level, which would mean it's in the URI, then require it to be in the payload. Or if we can't find thing_id at the root level in the URI, then require it in the payload. And then, of course, permit priority image_id and thing_id to come on in when we create our thing_image. And then we want to have some before actions. A get thing and a get thing image, and they would go as simple as that. So we're going to assume with parameter key for the thing is going to be thing_id, and the parameter key for the thing_image is going to be id. So before the following actions, index, update, destroy, we're going to be calling these methods and if they have trouble, they'll throw an exception and the application controller can pick up on the recovery. And then to finish out this private area, we have update parameters. Notice I expanded the name. Instead of calling it thing_image_params, it's, well here are the parameters that are appropriate for a create, and here are the parameters that are appropriate for an update. Expressing image ID or thing ID is not appropriate for an update, only changing the priority is appropriate. And then of course where would we be without authenticated user. We only require authentication from methods of create, update, and destroy. Methods like index does not require authentication, will allow anyone invoke the method, but as you'll see down the road we'll actually add extra processing if they happen to be authenticated. So there'll actually be two ways in which the method will act, whether it's authenticated or not as we get further on in the module. All right, so index is implemented through some query scopes, and we just finished going through that, so that should look pretty straightforward. Then we add image_things, coming from the image perspective, what things are linked with this image and included with that data, please include the name as well. And then to include some additional functionality, what kinds of things are not yet linked to this image? What things out there are not associated with this image? And as I said earlier, this is a URI that exposes the result of the not linked query scope. So next, we'll define the create method. It's got a bit to it. The fact that we can have our parameters coming from two different URIs adds some complexity here. So bring in the create parameters, and if anything's missing, it will throw in an exception and will be caught. But in addition to that, we need to throw in some URI properties, and we're taking care of that. And then after we have done error checking that says have you expressed the information we care about, we now need to worry about, is it valid information? Like, what if you've expressed a thing_id that doesn't exist? So what we would like to do is return an error message, a rendered bad request. And express in it what your ID is and what we were looking for. And we would like to do it in some kind of standard format. So what I want to do is go ahead and declare a helper method up in the application controller. And you see where this record_not_found? Well, let's break this thing down. There's an aspect of this method about returning an error message. Let's get rid of that. And then, here is the aspect of it that it was a record not found. So what we can do is factor out the payload formatting and the returning of a status and pass in the string that we want depicted as a full message and the HTTP status. Okay, that looks kind of clean. I was staring at that a while back I said, I'm going to need that. And the next thing we need is to assign the creator ID, and we'll get that from device. And then we have the standard processing block that we commonly see either coming from a scaffold or something that we would normally replace anyway. So at this point, create thing_image, the link between a thing and an image looks complete. Now we add the update method. It's kind of simple, now that we have our own helper method that gives us update parameters. And trusting that, we really don't need this extra slice, because that's what whitelisting is doing for us. So return no_content and thing_images. And destroy looks pretty straight forward so far. The controller looks like something that's not going to totally blow up on us when we start writing our test. Okay, so what we need to do now is create our views directory. So app/views/thing_images. And since I'm only going to return lists, I really only need to create one view file. I don't need to create a partial, so this'll be a decent example of just an all-in-one. So when I go to martial out my thing_images, from the thing_image itself we're looking for the thing_image id, the thing_id, the image_id, the priority, you know, all the standard stuff. I went ahead and readded updated_at late in the game, and then I want to add thing_name and image_caption. But of course, these methods are going to blow up if the query hasn't populated the result with those value. So I can't ask if they're nil or anything like that, what I have to ask, hey, does this thing_image respond to the method thing_name or respond to the method image_caption? If so, let's produce it. In summary, we've built a nested resource, thing_images. And we expose this resource via multiple URI viewpoints. Below things and below images. Things can have images, and images can have things. And the ThingImages represent the properties of those relationships. We took a look at how parameters could come from the URI or the payload. URI properties are automatically required, and we're able to make our payload parameters conditionally required, based upon the URI we recalled from. Our API was built to work with custom compound objects. We didn't separately go out and get ThingImages, images and things. We used query scopes from the model tuned to the API's specific needs in order to be able to get a compound response that very efficiently expressed the relationship between a thing and an image. For authentication policy we're going to require our users authenticate in order to modify a thing_image. You must log in if you're going to relate an image to a thing. From an authentication perspective, we are going to require that a user login in order to be able to create, update, and delete relationships between a thing and an image. But we will allow anonymous read access. So users will be able to see the images for a thing that they have access to, or the things for an image they have access to. And there's no point in having a single instance of a thing_image, we're always going to want to get the images for a thing and the things for an image, or a list of all thing images within constraints. What's next? ThingImages Resource and Authn Specs. Basically the same topic as this except we're going to test what we just developed.