#58 Nested Resources

18/10/2021
Transcript
Hello. So in this episode we're going to talk about nested resources. It's basically nesting tasks inside projects or nesting messages inside an inbox. So nesting, uh, one resource that is logically connected to another resource inside in our roots, in our controllers and in our views. And uh, here's an example of message resources in the visual guides. And they're going to, to try to do it in the action in the Real Rails app. Now you see I'm already going to try to use RO and Rail seven Alpha, so I think it's not going to really matter in this specific application that we are going to build with message resources, but in the future it's going to be fun to see what works and what doesn't work in Rails seven Alpha. So let's create a new Rails app. I'll say Rails new. Let's name the app like Twitter database, postgre sq, it's been created and uh, yeah, it's run Input Map install instead of uh, web pack install instead of young. Also installed Turbo. Let's see, installed, uh, turbo stimulus all out of the box. Okay, looks nice. So, uh, let's navigate to the application, run rails to B great And try opening the application. So I'll go to preview, preview run application. Now I get this error because I'm on cloud nine. So I will stop the server and go to the application config environments Development RB config hosts equals meal restart and it should be broken. Okay, so here's the new Rails app. I will uh, actually commit to gi. So GI at all GI commit main create app. And now I'm going to scaffold inboxes and messages. So an inbox can have many messages. I'll say rails generate scaffold inbox, uh, title and that's it gi. And we are going to scaffold message title and it'll be referenced to an inbox. So inbox references. Okay, now rails TB migrate. And let's again comment this to Git gi add all GI commit main, uh, scaffold, inboxes and messages. Okay. And now we can start the real server and we can start making the nesting work. So what is this all going to be about? Basically heavy, have our inboxes our regular route, we can create an inbox and to be able to see the messages that are related to this inbox, we would maybe want to navigate to inbox one slash messages and to create a new message for this inbox. We would maybe want to navigate to inbox one messages new. So how are we going to make this work? Well, first of all, of course we are going to add the, the associations go to our models inbox. RB has many messages and of course inside our messages you can say belongs to inbox, but it is done by default when they run the scaffold with references. Okay, so next we're going to go to our route. Let's have a look at our roots. Here they are. We have our messages that are at just slash messages without inbox ID slash messages. And we have our inboxes. And let's have a look at our roots, uh, file. You see we have resources, inboxes and resources messages, and they're going to nest messages inside inboxes. So we'll say resources, inboxes, do resources, messages. Let's uh, go back to our roots and see what changes. I'll go to a new roots page. And here we have inbox messages part, so not messages part, but inbox messages part. You see all the route for all messages are now nested inside our inbox. And let's see how it's going to work. So you see I go to inbox one messages for example, and you see we get this undefined local variable new message path. Why is it so? Because new message path does not exist anymore. Instead we have new inbox message path, you see, so it's kind of nested. Now let's see if uh, it actually works. I will uh, go to our views, update the index view. So go into our index. It'll say new inbox, message path, and we can pass in the inbox. Oh, actually it worked. And you see by default we have inboxes one messages new. Now if we go to our inboxes, let's just create a second inbox and navigate messages. You see it already sees inboxes two messages new. So the path works and navigate another error in our form build. We have and define method messages part because uh, we're trying to build the form for going to slash messages post, but we need to go slash uh, uh, inboxes ID messages post. So let's go to our messages form builder and we'll have phone with model. And here we'll need to pass in our current uh, inbox and uh, the new message object that is this one. So we will say inbox first, for example. Goma message new. Let's see. And it seemed to have worked. And here we also have this back to messages, messages path. So this one isn't working either. Now what are we going to do with this? Let's actually do it the right way here. Instead of just getting inboxes first we are going to find the inbox in the controller by the PERS id. So I will say add inbox. And you see we have no add inbox. So we are going to go to our messages controller controllers, messages controller. And here we're going to go to private methods and say Dev set inbox. And we will say at inbox equals inbox find, uh, grams inbox id. So this first is ID, is going to be the inbox id. And if you have messages slash two for example, or three here is just going to be the id. So we are finding message by ID and inbox by inbox id. Okay, and let's say that we will set inbox on the very top. So before action set inbox for all the actions inside the messages controller. Okay, let's refresh. Okay, so the form was built, but we have a further error in our messages. New partial uh, new template back to messages isn't available. So instead of messages portal, we have to use once again something like inbox messages spot. Let's go to our new page. And here we have messages spot and we would have inbox messages, spot and pass in the inbox. Let's save it works. So the new message view works. I can press back to messages and I will be directed to inbox slash two slash messages. Okay, let's go to create a message. And actually we don't want to be able to hard code an inbox ID here. This should make it, uh, automatically the inbox ID that uh, we are browsing, uh, uh, in the URL. So we are going to remove this from the form. So no more inbox, uh, ID input in the form. And uh, let's try to create a press create and inbox must exist. So we must add the inbox in the controller. I'm going to go to the messages controller. And here actually I'm going to say not just new, but uh, I will say at, uh, message equals@inbox.messages.build instead of just message new. So here we're going to initiate the inbox. Let's see if it works. I'll go back to messages. New message. Great message. It still doesn't work. So next we are going to go to our create action. And yeah, first we'll also remove this inbox ID from the message PERS user should not be able to pass it in. And we'll go to the create action. And here we will say add message equals At inbox. Do messages, build message brands just like this and let's see if it works. So once again, I'm going to create a message, create message. And you see we seem to have saved the message, but we get already the another error and define method messages. URL. Again, we should redirect to the, uh, at inbox at message. Let's see if it works. I will resubmit. So going to new message, create in the message. And okay, so now we seem to have submitted it. And uh, in the message post, we have no link to show message. So here again, we need to add the, the new path. I'm going to go to the post. And here we have at inbox coma message. You see it's uh, kind of, uh, troublesome and takes, uh, some time to adjust. All the code of the messages that are going to be inbox, uh, are going to be inside an inbox spot, usually worth it. Okay? So again, I'll try to create the message. Press create, uh, I still have something wrong in messages show here. It's going to be edit message path at inbox, at message. Actually you can say not at inbox, but you can just say at message inbox. But I think it's more correct to say, um, at inbox, but it doesn't really matter in this particular case. And here, button to Destroy will say at inbox, at message. And here, back to messages. We'll say, uh, something like, uh, at inbox Goma messages, I think this should work. So it would, should lead to the inbox messages path. Let's see if it works. Again, resubmitting great inbox. Okay, this path doesn't seem to be broken. And define method, edit, message path, edit inbox, message path. Sure, Resubmitting again and it failed. Okay, let's show this message. Let's, uh, go back to messages. You see it leads us to inbox two messages. Let's try destroying a message and we still get an error and define method messages, URL. So again, if we need to go to the messages controller and uh, say that if we destroy a message, it should redirect us to something like inbox messages. Let's see. Okay, this message doesn't exist anymore. I'll go to inbox two slash messages. Uh, I will destroy this message. And you see they're directed back to the right path. And I think we still need to do our updating. So, uh, here we should direct, direct, not to the message, but to the at inbox coma message. Okay, and now let's, uh, try going to, let's say inbox one messages. And you see, we see the same messages. So in inbox one, we don't want to see the same messages, we want to see all the messages that are relevant to this inbox. For this, we're going to go to our index action and say messages equals at inbox messages just like this. Let's see. Okay, in this post inbox, we don't have any messages. So let's add one message for first inbox back to messages so the Nest inbox correctly. And actually we can also do something similar inside our set message. So instead of having the message message find pers id, we can uh, say message equals inbox messages, find per id. So this way actually it should potentially search for the messages a bit faster because they're searching not between all the messages that they have in the application, but only between the ones, among the ones that are relevant to this inbox. So the search scope is, uh, a bit smaller if you have like thousands of messages I guess. Okay, so, uh, seems to look fine. And this is basically how you can add the message resources. But, uh, let's go another step, uh, further, you see in our views folder we have inbox and messages and also in our controllers we have our inboxes controller and messages controller. And logically, uh, it'll be good to also nest them in the views. So let's say we'll want to move the folder of messages into inboxes. Let's do it like this. Okay, uh, I guess yes to all. Now if I refresh, you see no template. So the controller doesn't know that it needs to go to this template. Now we could actually potentially just, uh, say in each action that we want to redirect to a template that is nested, but it would be better for us to also move our controller into a folder. So I would say new folder inboxes move the messages controller into inboxes. And here, will it work? No, it still doesn't work. So we are going to say that it is going to be in the module inboxes. So we are just saying that it's kind of in the this folder and that, uh, the messages are in the inboxes folder in both views and controllers. So let's refresh. It Still doesn't fe So sidebar says that, uh, it didn't manage to find the path. It is because we need to go to our messages controller and say that, uh, it inherits from the module inboxes. So inboxes, messages, controller. Now I go back and it seems to be working. So let's just go back and say inboxes. I will create a third inbox. Okay, now I'll go to the messages, I'll create a first message for the third inbox, I'll Mm. Let's go back to messages. New message. I'll try updating. Okay, here in update, I didn't, uh, change the links. So I'll go to edit here will have, uh, show this message. So in messages edit, let's go to messages, edit. We have show this message. It'll say at inbox, at message. And, uh, inbox messages pop, uh, at inbox. Let's see if it works. Update and ITFers. So this is basically how you can use message resources in the Rub rails application. Now at first glance, it can seem like a lot of stress on updating all the scaffolds, but again, usually when working in a Ruby Rails application, you don't really do everything by scaffolding. So I really had to update each of the views and update the links to work, uh, inside these message resources. But usually it helps you keep the logic of your whole application, uh, in, uh, intact. And you'll always know that messages belong to inboxes and you'll know that you can access them both in controllers and in views inside your inboxes. And it is easier to scope the messages. It's easy to find the inbox ID for each message at the glance. And you have the nice, uh, logically correct URL. So that's basically it. This is how you can really use message resources in, uh, your views in Rails application. So thanks for being with me and have fun coding.
0
Join the conversation
Sign in to access PRO lessons, access private repos, leave comments, create watch lists.
We collect your email address, name and username to create your account. We do not share your email address with anyone else.