Rails Tutorial | Building a Real Messenger App with Rails 6 and Action Cable

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up guys Steven from tech maker TV here in this episode I'm gonna show you how to build a fully featured chatroom application with Ruby on Rails 6 with action cable this isn't going to be your typical chatroom app this is going to be really quite in-depth it's going to keep track of which user is posting what I'm gonna show you how to manage different connections so if you jump into a different room it'll work the way you expect a chatroom to work so yeah that's gonna be a pretty cool episode I hope that you're ready for it so it's gonna take us a little bit it's probably gonna be a couple hours long I'm gonna go ahead and suggest that if you're not familiar with action cable at all check down in the links because in the description because yesterday I created a video it's about 20 minutes long it shows you sort of the ins and outs of action cable I'm kind of learning it myself so I just kind of did an exploratory session so if you're interested in that definitely go check that out also check down there if you're interested in any of the other more in-depth series that we're doing right now we're building out a link shortener with rails 6 and I've got another series that's happening right now on building out a stock market tracker with react Jas so if that kind of thing sounds cool you definitely subscribe to the channel and if you want to see more long-form content like this leave a comment below and let me know it's a little more time consuming for me to do that's why I typically break it up but I'm here to make stuff that you want so just let me know in the comments what you prefer but in anyway let's go ahead and get started all right so let's get started I'm gonna try to fly through this a little bit so first of all let's just check the version we're running here so for future reference this is rails six point zero point two point two so let's kick it off with a new app so I'm gonna just call this chatroom rails new chatroom just accept all the defaults keep it simple okay so now that that's installed let's just change down in to chat room and open up the code all right so let's go ahead and just close some stuff move some stuff around on my screen here a little bit all right so yesterday I put out a video about exploring action cable and I'm not gonna repeat all of that here so if you're curious about why we're doing some of the things that we're doing you can go check that out but just remember that you will need to install Redis if you don't already have it so I'm gonna open up my gem file and if you don't have Redis installed on your computer you'll need to do more than just put it in your gem file just a heads up so check out the video if you're confused but we can bundle install after adding Redis to our gem file and then I'm also gonna open up the cable about yml file change this from a sink to Redis this is just a little bit of setup that we'll need to take care of okay and then I'm going to copy this URL and put it here okay and save that and we should be good to go as far as all of that is concerned I'll leave a link to that video down in the description so it's easy to find if you want to check it out and get a little bit more background on all of that setup and probably some of the other things we're going to do as well I'll try to cover mostly what's happening but there may be some details that we kind of gloss over so we do have to do a fair bit of non action cable non WebSocket setup here because we're building this out from scratch and I'm gonna do that hopefully as quick and painless as possible because I know if you're watching this video it's because you want to learn how to do the action cable real-time chat kind of stuff so I'm gonna try to do this really quickly and to that effect will probably won't write the cleanest code in history we're gonna leave a lot of scaffolding laying around because we don't really care about that right now so let's go ahead and just do that so I've got the idea of or essentially three models we're gonna just have a chat room concept where you can a user can create rooms join rooms so on and so forth which means there's a user model and probably a chatroom model and then there's gonna be a message that kind of sits in the middle and has a mini - mini relationships so let's go ahead and do that so let's say rails G scaffold and then we'll call it just room and it's gonna have a name and we'll leave it at that for now and let's see what else are we gonna need we're gonna need to have a user and I'm not gonna make a scaffold for user I'm gonna automatically create users so to keep it simple you're just gonna get assigned a username when you hit the webpage with a session so we're just gonna create a model for user and give it a user name and then we'll add a validation that the user name has to be unique over here so just do that really quick so validates uniqueness of user name okay and then finally let's create a thing called a message rails G let's give it a scaffold rails G scaffold message and it's gonna have content text and it's gonna say user references and what do we call it room references okay and let's migrate this stuff and hopefully we did that properly okay cool nothing exploded so far so good okay so let's open up our routes and you can see here we have a couple of resources already from the scaffolding and I'm going to just say routes and we're gonna say groans index for now okay so let's run on our server over here and let's open up our browser it should be right there okay and let's hit localhost 3000 and see where we are in the world okay so we've got the ability to create rooms here and you can see that basically we just have our standard scaffolding material going on okay so I want to grab the bootstrap latest CD in link over here and we're gonna use that for our styling here so let's go ahead and just open up application HTML by ARB and paste this thing in right here if this was a real project I would not bring this in with a CDN but I'm trying to just keep this simple and so we refreshing we see that our style changes so I know bootstrap is in place it looks like everything is working right I'm also not worrying about any of the JavaScript all I really carry or care about is the CSS so let's go ahead and start building out the front end for this a little bit okay so what I am envisioning is something where let's open up our rooms index so I'm kind of envisioning something that looks a little bit like slack maybe not exactly I gotta spend that much time on the front end here but something where you have a list of rooms on the left and then when you click on one you're into that room and then you're kind of chatting on the right so let's think about how we could do that so with bootstrap and I'm not here to teach food strap or anything like that so and this might not be the best execution of it anyway but I'm gonna do something where I have like container fluid and then I'm gonna make a row and then let's say that we have a column let's say like three I'm not gonna even worry about this size of the browser just gonna say it's a three column nine column column nine then what I want to do is say for each of my rooms well first of all at the top let's just put a card card body and all right here we could put the form for a new for a new room right so we could say render what is that form just for them like that and then we could just say room is room dot new see what this looks like okay so we have our we have our room form there yeah I don't need that in a card I don't know why I'm doing that it looks kind of silly just put that like with an HR tag under it or something yeah that's more like it okay then that's open up that form because that looks like crab so rooms form let's say class is form control and then down here we'll say class is BTN and BTN primary beats Ian block does not like to have the class right there probably okay fine let's just say add room okay so not the most beautiful thing in history but we don't really care right because we're trying to run through this and it's not supposed to be beautiful I'd say that I do care a little bit but I'm probably gonna just come back at the end and clean up the look of it a little bit if we want to maybe we will maybe we walk we shall see so anyway what I want to do is under this HR tag I want to actually print out my list of rooms and we're going to make it so that if we click on one we actually don't really want to leave this page I just want to like sort of load the actual room on the right side so let's start by just printing out the list of rooms and linking to them so we'll do is we'll just say at rooms dot each do room and what I'm thinking is maybe we will do like how should I do this I could make it a card yeah let's make it a card because we'll probably stick some stuff in there in a minute it's sort of my go-to element if you can't tell so when all else fails use a card so what I want to do actually is link to this thing so we do need to print it out so we'll say link to and what I'm gonna do is say how can I do this I'll be just like room path well now I want to say rooms path but then I want to say room ideas let's see let's just do a room path and what we're gonna do is just change the I don't know I can't make up my mind about that let's come back to that thought in just a second so we need to do link to whatever the path is do and then in here we'll just say room dot name for now and let's refresh this thing no route matches I can do just room okay so now we have room one here hover it does this weird business click it goes there okay so it's doing something ok so what do we want to do now is open up our rooms controller and what I want to do is actually in show here I'm gonna say at room equals well they actually have that already it's the default scaffolding so down here so we're already setting the room fine but I want to actually add is this at room at rooms equals room dot all and then I'm going to render index so now it's gonna look like nothing is happening here so if I click this it's just gonna actually just go nowhere on the front end but if you look at the URL we're actually at rooms slash one which means that we actually have an at room so what we can do is over here and again we're gonna be kind of changing this up as we go but we can say if at room presents let's just print out the name of the room and a P tag for now so at room dot name and let's save that if we refresh we can see there and then if we go back to just slash well if you just go back to our home page there's nothing right so it's like we're kind of missing a logo or something up here to click on to go back to the root path okay anyway so we don't need any of this stuff down here anymore at all so let's just axe bat or fresh and let's try to add a room and see what happens so add room and we're getting this notice up here which I don't really want because we can tell that it was created by the fact that we just got redirected there so it's a groom room 3 so now we're in the room we just created we can jump between all the rooms so that's cool I don't like how these things are right up against each other so let's say card and then MB - which is margin-bottom so give it a little space alright so let's talk about what we want to do next basically what I want to happen is on the right side here I want to turn this into kind of a chat box like you would have on slack or even on your phone and text messages so at the bottom of the screen we're gonna have an area where you can type in a button or you don't even have to probably have the button you can just hit enter at the top we're gonna have kind of like a nav bar looking thing that tells you which room you're in so on and so forth and how do we want to go about doing that first of all let's just inspect this I'm gonna pop this out move it over here and so how tall is this thing so what's at the top so we have what is creating this padding I guess that's probably coming from what is doing that so clearly have a margin maybe that's coming from the scaffolding let's look inside of assets over here style sheets so margin 33 pixels I'm gonna delete this scaffolding stuff because that's gonna interfere with other things and we've got some empty CSS files here you know I'm not even gonna worry about cleaning it up I just don't want the scaffolding to mess with my stuff so if we push that out now we're gonna break our nice little layout we had going on there and we actually kind of fix our links so that they're not turning white when we hover so okay so the scaffolding was giving us some stuff that we weren't paying attention to so we have to clean this up a little bit that's okay want that to go from top to bottom over here so now what I want to do is say if room dot presents I'm gonna create a new div and let's call it let's just call it chatroom sorry if you've been getting a bit of a scratchy noise that my mic was hung up on my shirt so fixed that hopefully one of these days I will enter into the future and get some Bluetooth headphones or something okay so let's keep going with this so what do we want to do here so I need to create in my JavaScript folder over here I'm gonna create a new file called application no I'm gonna create a new folder called style sheets and then I'm going to create a new file in here application is CSS and in here I need to import style sheets application dot F CSS and then back in here I should be able to do like chatroom let's just make sure that we're actually hooked up and I need to open up application dot HTML and make sure that I change this to style sheets pack tag so let's see what that does not a bad thing all right where do we go wrong okay I'm just gonna click inside here chat room I have chat room background color well it is getting my styles but it has a height of nothing apparently supposed to height not hack height 100 B H which is view height so it should be just the height of the browser because we took away all that padding that should be exactly okay cool so I didn't put anything in the chat room I let the outside of it which makes more sense all of a sudden okay so now we've just got that black box which is not useful but still it's there so what do we want to do now okay so I don't want the background color obviously I want to make this where the overflow Y is hidden because we don't want this to scroll I want everything just scroll within and okay so now we're coming back to where we were okay so in the next couple of minutes this will hopefully start to come together a little bit more so what I want to do is I'm going to create a new div down here and I'm gonna call it chat box maybe that sounds reasonable and then what I want to do in here is render the form from the messages scaffold so you we haven't even looked at that but there is an entire other area over here called messages that scaffolding generated for us and honestly we're just going to ignore that but we need to render this form for a new message and it's gonna be a message new and this may break yeah so what we've got going on with the message situation is it's trying to manually take a user in a room because it references those things and it's basically saying hey I need a user ID and I need a room ID and that's because of how we set up the relationships when we ran D migrations or the scaffolding kind of stuff rather and we obviously don't want to have to enter in my user ID as this in the room is this so what we're going to need to do before we really proceed it's fixed that so let's open up the messages form and we don't want any of this except for the user ID there and we really don't want we don't even want anything with the user ID what we do want though is a hidden field for the room ID and that we will provide let's say a room ID he didn't feel I think we just say room ID like that and then what we'll need to do is pass the room along from the render over here alright so let's refresh and let's see what that does if it explodes or not undefined method merge I think this format I need to save value like that okay cool so now we just have a content box with a button we try to run something in here it's gonna blow up and tell us hey undefined variable room for okay so it's redirecting us back there that's kind of weird let's see what happened in a database so I want to see if it created a message no it did not create a message so I think what happened and let's check in the thing here so if we just follow the flow so we have a rollback of transaction here which is what I was expecting to happen and then it just tried to render basically a new form or something in the messages but because we don't have the variable blah-blah-blah-blah-blah it didn't work because we don't have a user as basically what happened so trying not to get too hung up with the details normally I'm doing much longer series I'm trying to cram a bunch of stuff into one single episode here so let's just kind of cut to the chase if you want to get a lot more detail look at some of my longer series where they're like a gajillion parts and I kind of don't spare any details for the most part okay so let's look at what's going on here all right so let's have a quick look at the message object also message model so you can see here we have this belongs to user and belongs to room and now whenever you specify these things active record essentially won't let you create anything unless you have them so they're required by default essentially so what we need to do is say at message user equals current user and so this is sort of applying implying sorry that we actually have a current user which we don't so let's open up our application controller so what we're going to do here is say current user and what we want to do is basically say if we have a session ID user ID in the session we're gonna just use that user otherwise we're gonna create a new one so essentially when whenever somebody lands on our page if you've never been here before or you don't have an active session we're just gonna create a user for you this is obviously not how you would want to do this in real life but it's fine for what we're doing because it's just an example so what I'm gonna do is say if a session we might change this up a bit in a second not sure if session user ID dot present I will say at current user equals user defined session user ID else and we need to actually say current user equals user generate okay and then we'll say session user ID equals at current user ID and then up here and then I'm just gonna kind of put a guard statement and I'm gonna say return at current user if current user dot present and the reason we're gonna do that is because we don't want to run through this query every time we call the current user method okay so what do we need in here we need this user dot generate business so let's go to end user and then I'm gonna create a class method called generate so we'll say def self dot generate and I'm gonna just do something kind of like so we have to have a unique user name so let's actually do something where we have like so I think I'm gonna do something or we say like adjectives equals ancient gotta think about this broken creative dangerous really hope I don't misspell any words right here effective flying and gilded or I was about gilded I guess that's right okay and I don't really like broken that's kind of sucky to give somebody as a username and then we'll say nouns equals start what's after G high way in turn really having to get creative here jackhammer and maybe like lion and [Music] master okay and then what we want to do is get a random number probably like three characters so we can do something like R and 2's 2.4 I think so let's look at our B for a second just a quick explainer on that so if we just type around we get this long decimal so if we convert that to a string we get that and a string can be accessed with a ray or square bracket type stuff so if we get you know each thing position by position we can get to the different stuff so this is actually just selecting this segment basically so we're getting you know it's pretty quick and easy so now let's look at what we've got here so I want to say username equals a string so I'm gonna say adjectives that sample - noun stats sample - number and then I want to say so that's highly likely to be unique I would think at least for our purposes it is in reality we would want to have a ton more adjectives and nouns to get more interesting stuff going but all I'm gonna do now is just say create username username he's right okay so let's see here if I so I have current user in our application controller I'm gonna write helper method current user which is gonna make that available everywhere even in the views that King is how that works so what I'm gonna do now in my index page for runes is just at the very very beginning we're just gonna say hello current user die user name and let's see what happens here if i refresh undefined method for one integer what in the world happened there application controller maybe I need to okay so probably would work on a refresh flying highway 503 okay I can live with that alright so to be sure that this is doing what we expect let's open up a new incognito and oh and their local host 3000 now I'm effective lying one more time for fun effective line seven sixteen that change no it's like probably have another incognito window open somewhere and it's like keeping this session so we'll check on that momentarily but it seems like it's working okay so now let's go back and try to create a message here so first of all I need to go in my room and say has many messages alright and so then what we want to do is just inside of our chat room here directly inside for now I'm gonna say at room messages that each do message okay and we'll just make a pee tag and say message content right and then in our messages controller when we create a message don't want to do any of this stuff I just want to redirect to request refer refer and let's see what happens here I'm just fine method referrer for their misspelled that maybe that's referrer with to ours so let's go back here go to room one go to okay so my message did get created in one to see if I spelled refer correctly this time unknown format respond to do format I really don't care about the format I don't care about any of this stuff that's probably a bad idea I just want to back up okay an actual fact I just want a message dot save and then redirect cool can deal with what goes wrong later okay that's what how it's expecting so I did warn you at the beginning of this video that we would be writing some sort of maybe shoddy code or less clean code than normal and that is the fact because we're moving really quick through this so let's work on how we actually present it so right at this moment we have the ability to create messages and display them it looks like junk and we're gonna fix that entirely let's actually one thing really quick so we have message that content and then I'm just gonna say message dot user dot username right beside it so it's telling us flying highway 503 said that we go back to our incognito with effective lying over here if we click on room 2 we can enter in so now we actually have a chat happening right it's just not streaming anything so I have two things left what we want to do here we have a full chat room app running but we need to be able to essentially have these live update and I want to fix the styling first because it looks terrible okay so let's go to our first of all let's take our chat box here and let's fix that so where do I need to go to do all this so I have a bunch of crap open I'm going to close it all and open it back up rooms index is what I need and then I need a application scss okay so down here I have chat rooms and I have chat box nested inside it so I'm going to do this and I'm gonna say position fixed to absolute and bottom zero and let's see what this does nothing oh there goes I just headed the way okay cool got worried for a second so now what I want to do is go into my messages forum and I'm gonna fix this a bit so first of all I'm gonna add class form in line there then down here I'm gonna take away the label cuz I don't care I'm gonna make this a text filled content and class on control and I think I need to make this a forum group I may have to go reference the bootstrap Doc's here in a minute I'm gonna bump this up above and then this I'm gonna just say so I say add message and then we'll say a class b10 BTN and primary okay so I've got now a input down here and I've got my message box so I can just type and click Add message and now you can see that that's added right there I've got to quit typing the same stuff over and over and over again okay cool all right so what I want to do now is just make this thing just put some padding on it not left all so we might get 15 pixels and then let's say input type equals text I'm gonna make the height on this 45 pixels the font size what's called 18 pixels and padding 10 pixels I might be too much say 8 pixels I have no idea let's refresh the page and see what it looks like okay so now I've got a bigger box there and it's got some room from the bottom I'm gonna make that 20 because I want it to kind of be a little bit higher up on the page and I want this thing to go all the way across I need to also make my button the same height hi 45 pixels I'm gonna have to deal with padding and whatnot - it looks okay cool I'm gonna add on this guy did margin right - okay and then how can I get the width on this thing to go all the way across that's would be nice farm group what's the way to the forum can I just do like with a hundred percent and get it going all the way across no until investigate the bootstrap Doc's for just a second I think I have an answer it might not be like the best answer but I'm just gonna go ahead and do this really quick so instead of form group I'm gonna call this input group and if we look nothing changes if I change my chat box to have a width of a hundred percent see what that does so now you can see that's going all the way across and it's actually causing an overflow in the x-direction which I don't like so I'm just gonna do a quick calculation here 100% minus 15 pixels which should account for the difference there and bring us back on screen so let's look that looks to be about right everywhere so the last thing I want to do is add some placeholder text here so let's just say placeholder type your message here okay and let's see little guy okay cool so now this looks pretty good so one other thing we can do that I just looked up I'm gonna get rid of this mr2 here and this may fix our width problem so if we do div input group append let's see what that looks like so those are now joined at the hip I still I think the width is fine I don't like that outline probably take that away later I'm gonna worry about more styling with that after a while next thing I want to do is make these messages look better because right now they look like just text printed out because what they are so what I'm gonna do here is a div class equals message and then in here let's say message let's just thought it was like content maybe print out the message content and then under that let's say div class equals author maybe and then we'll copy this thing so not to retype everything on here again okay so now let's say mmm what I'd like to do is say something like I'm gonna add another class of me if message dot user equals current user okay so let's refresh this and let's see so I'm flying highway 503 so let me inspect that so got content me actually I'm gonna put that up in the message class okay cool so let's ask this from here put it there okay so let's go over to our application CSS and chat box actually this is not in the chat box this is in the chat room so we're gonna say a message I'm gonna say background-color e that's actually gonna be the content and we're gonna let's say padding 10 pixels border radius 15 pixels see what this looks like okay that should not be a hundred percent wit mmm how can we fix that so what we want to do is set this as display:inline-block so that the content register there we go save that so now the content should it should only be as wide as the content inside of it basically okay but we obviously don't want that to happen like that so what we're gonna do is let's see maybe we should put a break tag after each one see what this does okay so now it's wrapping in the way that we want I'm actually gonna make this have an mp3 so do we get some spacing on these things okay so let's add a longer message like hi this is a much much longer message to see what happens okay so that looks pretty good I don't like the padding exactly as it is with these things I'm gonna bring the padding down to eight and bump that up to 20 and let's see where we are that looks better and actually I'm going to say padding eight and then 60 let's see if I have that order right I may not I sometimes get that backwards okay that looks cool now what so what we want to do is underneath we still haven't addressed the what's it called I don't need this open right now the author so dot author what I want to do is say let's make this font much smaller so font size let's just say 12 pixels or 0.78 Aria maybe color make it gray and let's make it though let's bump it to the left just a little bit which is it right rather see what that looks like okay so what I want to do now is first of all that looks a little bit big what I'm gonna do is make this where if I'm the one who said it it's gonna float over to the right and have a blue background with white text so very much like if you're chatting on iOS or something like that um in order to do that I need to make a couple of I don't want a copy you want to inspect things make a couple of changes here so how tall is that 59 pixels is that right so if I say here to my message I say men men height and I say 59 takes a little - what does that do nothing I say 60 does it go up yeah so I want to leave it at 59 okay so in my application SCSS gonna say men height 59 pixels okay and what I'm actually gonna do I think I'm missing a div basically so I'm gonna say div class equals [Music] content container and I'm gonna bump these things up into it let's refresh and see what we've got so far okay so nothing's happening really what I'm gonna do is I'm gonna wrap these guys in a Content container so that I can move them around together okay not one did not want to go all the way down there okay then what I'm gonna do is bump this display:inline-block into the content container okay that didn't work as expected why did that do that let's investigate so we've got our maybe it's because I have a br tag hanging out somewhere I don't need it anymore okay so let's try that okay yeah so now we're back to where we were so what I want to try is just what happens if I float this guy right now hopefully they just all say stacked up exactly like this and move to the right okay perfect so I don't want to float all of them what I want to do is if you've got the class on the message of ampersand or of me so I can do ampersand me dot content container float right so let's see what that does hopefully I got that syntax right okay so now we can see here that we've got everything that I said over here and then effective line is here so that's exactly what we were hoping for so now what I'm gonna do is say that content background color what color is the primary color in here what is that that's what I want this is gonna be very blue and white and color white and let's see what we got cool so now we've got something nice looking and happening here okay so the last bit of styling that I want to worry about for the moment we're gonna do some more later but the very last thing I want to do is fix this room to label up here so we're gonna look up the bootstrap navbar really quick and I'm just gonna grab I don't want anything fancy at all I just want like this and we'll put that in right here where we have that room name I'm gonna just replace this and I don't actually want that to be a link or anything maybe I can make it a span and let's get rid of the P tag there and let's see what this looks like okay so now we can see here that that is we're gonna have to worry about like scrolling and stuff at some point so in actual fact this probably needs to be a navbar fixed now how that works now let me do a quick search here fixed top is what they needed to say okay so now we have another issue because it broke out of the container so you know what for now let me just take that away we'll worry about that later I don't want to cause any additional problems for now I'm just gonna give this an MB for so that it kicks stuff down a little bit and now that looks better it's not gonna work quite right so once we have like this really hooked up I'm gonna have to come in and figure out how to make this like kind of sticky here and then have stuff scroll under it we're also gonna have to deal with the issue of we want this to scroll all the way to the bottom when the page loads because you imagine there's like a long conversation here you want it to load at the bottom and when people chat you want the screen to move up so we'll have to worry about that little bit of animation at the end the other thing I'm going to do here is just grab this a little bit of text there and how can I do this so what I want to do is say something like UL li class equals nav item paste that in there see what that looks like not at the whole what I was imagining I'm gonna do a quick search in here for nav item nav bar nav I need to put that there okay let's refresh okay so that's fine so we're logged in as flying highway 503 okay everything looks pretty good from this point like I said I'm gonna come back at the end and tighten this up even more because I decided to make this as nice-looking as possible I guess so let's move on let's get this working like a chat room now all right so first things first let's go ahead and jump back over to our terminal so now I need to create a new channel so I'm gonna run a command and rails rails G channel and I'm gonna call it room I think let's just call it room yeah okay so that's gonna generate a few things and again we looked at it we looked at this in detail yesterday in this example over here so we're gonna use some of that material if you want to see that done in depth you can look at that video but let's go ahead and get going okay so over here in our file tree we can see we have this channels folder room channel now and what we're gonna do is the same thing we were doing yesterday so we were looking at something like this so room channel and then underscore and then we have a params object and we're gonna say params room ID all right so once we have that we need to go down to our room channel JavaScript and fix a few things in here so instead of just having room channel excuse me what we're gonna have to do is say channel and then come over here so we're basically gonna pass in an object with params instead of just directly saying room Channel and then what we want to do is say room ID and we're on room 2 over in our browser right now so let's just hard code so now that we have that inside of here let's just console dot log connected and then let's open up our console here and refresh the page I also restarted my server off camera my computer actually just freakin crashed on me so that was weird so anyway you can see here that we're connecting to the web socket and room channel is transmitting okay so let's hook up something to handle receiving data so let's just actually consult about log when we receive data no it's just console dialogue good data actually and let's think about how we want to do this so back in our messages controller which we haven't done much with really here we have when we create a message we're redirecting to request out refer why don't we just get rid of that entirely and let's just say what is it it's action cable dot server dog broadcast and we want to be on the room channel and remember we want the ID for the room so we're gonna say at message dot room ID and then let's just pass in a message really quick so let's just say message hello we're gonna need quotes around that for that to do anything and then back in our room channels yes we're just console logging the data I don't need any of this open okay so let's see what's gonna happen here where's my terminal okay so I want to see that and then I want to see the actual developer tools so let's just see what happens here so if I type in a message and I submit what happens nothing happened so it broadcasted to room channel two message hello am i connected to room channel two is that what it is room channel room ID is two so I should be connected on there I didn't receive any data though okay so it looked like I actually just didn't save the room channel dot RB file so now I say that and now let's check out what's happening here so I'm gonna refresh says I'm connected and really type anything in there we get our message hello print it out and that's just because remember we hard-coded that right here to say message hello so let's actually hook this up to send over some HTML that we can append to the page so what I want to do instead of passing in a message here just a little hello I want to send in some HTML so what I'm gonna do is say HTML equals render partial and then I want to look at Oh what is it it's messages message which doesn't exist yet so we're gonna have to make that and then the locals just gonna have to be at message and actually that's got to be a hash so we'll say message like that and I'm actually gonna go ahead and split this on a multiple line so it's a little bit easier to read and then we'll say hTML is HTML okay so now we need to actually create that so we need to create a partial in here new file message that HTML by ARB then what I'm gonna do is come over here to my messages thing here and I'm gonna cut all of this I'm gonna paste it inside a message so now what I can do is just say render messages message for my main view actually and then we'll just say message is message and let's refresh and see where we are okay so we broke everything I guess I mean I've got a bad habit of not saving things today okay so now we're back alright so we are still console logging out the data here so let's take a look at what that's gonna look like so if I just type in some stuff here hit enter it's redirecting but you saw it flash if you didn't you can rewind and pause a little bit it flashed out our HTML there let's actually open up our incognito window again and go to channel 2 so I'm now dangerous master 9 1 2 which sounds a little crazy but whatever let's open up so keep our console open there and just type in something there and you can see that oh I'm not on that channel anymore only refresh on this channel go back we gotta fix that little redirect thing there but let's go ahead and just see if we can get something to print out okay so you can see here that we're printing out the HTML that we want and what we need to do now is fix this because this is broken this needs to scroll basically okay so back in the code let's open up application scss down here so we have overflow why hidden let's make that scroll refresh now we should be able to scroll all the way down clearly we have some layout problems here but I'm not gonna worry about that too much for now let's just go to room one and talk over there because there's more space what that means is we're going to need to set our ID to one right here until we get ready to not have this hard-coded okay so first and foremost this is redirecting because we are calling render right here and we don't want that to happen so what I'm gonna do is I'm gonna write a new background job that's going to execute this stuff so that we're not doing this in the context of the actual controller here so I'm gonna run rails G job and then I'm just gonna call it send message and we'll have a look at this so if we go into our jobs directory now and look at sin message job so we have this perform method and that's about it so we want our perform method to just take a message and then in here I'm gonna copy all of this for now and just paste that and then this will become message and message and render will become application controller dot render and let's see what this does okay so to do that we need to go back over here and we need to say a send message dot job dot perform later which is what kicks it over into the background and then we'll pass in our message okay so I think we need to go back and start our server again okay now let's try this let's go ahead and open up our console here and let's type in a message okay cool so now you can see that that got sent out and you can see here we basically just have the HTML so on and so forth so that's really great now what we need to do is append this HTML to the page okay so how can we go about doing that let's go back over here to our room channel and badge is actually gonna close all this stuff I keep too many files open so go room channel DJ s and then I'm gonna open up our rooms index so what we want to do is look in here in our messages we have our I'm gonna put a div ID equals messages right then I'm gonna put those there let's just refresh over here and see what it looks like okay that's fine okay so now what I want to do is actually append that HTML to my messages so I'm going to say let's we can do const message container equals document dot get element by ID messages so what i want to do here is a message container dot inner HTML equals and then we're gonna copy this and say plus data dot HTML let's check our what's getting sent back there so we need to look at the messages when you go get jobs send message yeah so I think we need to call dot HTML on that so let's refresh this and see what happens when we run this so I'm just gonna type in yo hit enter and let's check our console cuz we probably did something wrong cannot read property innerhtml of null which means I let's see here [Music] you know what I did I did this sort of backwards I need to say messages outside of that not sort of backwards you did it totally backwards and I did it for an individual message not one message okay so let's try that again okay sweet so now we're actually adding our messages to the page however there's an obvious problem here which we need to sort out which is that it's not recognizing that this is actually me and that's because our session so once we kick this over into the background job it is no longer aware of a quote-unquote current user because there's no session at that level so we've got to kind of work out some other way to handle that so what I have in mind is actually changing this up a little bit so instead of just sending HTML what I'm gonna do is send one it says mine I'm gonna send another one that says theirs and then I'm gonna do something down here and say mine mine there's there's and then I'm gonna send along the original message object okay and in here instead of saying message I'm gonna say mine and I'm gonna say theirs and now I have to create these now this is gonna create some duplicated code and I'm not actually sure if this is the right or best way to handle this but it's a way to handle it for now that gets us in a space where this is working so I'm going to create a file called mine I'm going to create another file called theirs and I'm gonna copy this code exactly so in mine it's gonna just say me because it is indeed me in theirs I'm just gonna remove all of that so that it shows up in the right spot okay so we have mine we have theirs in our send message job we're sending both the partial for mine and theirs and the original message and so essentially what we're doing is we're saying okay because we don't have access to session here we can't figure out who this message is from necessarily or who it belongs to rather I mean we know the user ID on the message but we don't know which connection we're sending this to or at least we might but I don't know how to do that so this is how I'm doing it right now so then what I'm gonna do because in my browser by the time I get back to the console I have I actually just added this that this div ID user ID up here so you'll need to add this basically all this is doing is it's saying put a user ID on the page so that it's embedded on the page so that we can access it later and then what I'm doing here is I'm calling basically just get the element by ID and then grab that attribute and we actually need to convert this to a number I do a little bit of work off-camera to try to figure out what the heck was going on with this so these are the only three lines of code that you I think is those two and the one up here at the very top so then what we're gonna do is we're gonna say let HTML and that's just going to be an empty variable for now then we're going to say if user ID is identical to data dot message to user ID because remember we're sending the original message object right here and that has a user ID so if those things are equal HTML equals data dot mine else HTML equals data dot theirs so I know this is a bit of a strange way to do this then the last thing we need to do is instead of data dot HTML do just HTML so let's try this thing is my server running okay so I'm going to refresh a couple of browser windows so here I have an incognito I'm flying lion 495 now we're here I have flying Highway 503 so let's try to chat between these guys so we'll say hey there and so you can see now it's saying okay this is mine and over here this is theirs and then we can say what's up sweet so now we have a functioning chat so the last thing I want to do I'm just gonna move this over and let's go to the code so the only thing we don't have like hooked up that you might consider essential is if we switch to room 3 it doesn't actually work because it's hard-coded which room are in so what I need to do is a very similar thing on my index appears so I need to say again it's a room ID is data well the room idea is the idea of the div and then I'm gonna say data room ID is at room ID now remember if I'm if I'm on the route path it won't have a room so I'm just gonna do dot try and this is gonna be nil if there's no if there's no room okay so what this is gonna allow us to do is back over in our room channel so the first thing we need to do is actually not execute this until the page loads because we can't pull stuff out of the HTML until it's loaded so we're gonna say document dot add event listener and then we're gonna say turbolinks load and then just an anonymous function here and then let's kick all of this back up into there and finally I'm going to so turbolinks is loaded at this point I'm gonna copy this stuff here and I will actually probably call this just user element instead of element user element and then up here I'm gonna call this room element and then I'm gonna say Const room ID equals number data room ID and that needs to be room element I just do it click fine for elements to make sure I didn't miss any of those variable names I think I'm good so then all we need to do is say room ID so now we have that as variable and I'm gonna say connected to room ID in my console here just to be sure so let's refresh this make sure that we're getting something going on nope unexpected token missed a comma somewhere yeah looks like right there I'm missing a comma right seems to be the case let's refresh and let's see what we got okay so now it says connected to 0 so I have another problem so what is let's inspect the page room ID is 3 so I do have my room ID on there so why is it then take away this number thing and room element room ID connected to null Oh I did not change that okay so now I'm connected to three down here that's weird though because shifts still gotten a user ID let's just try this though so let's try this so we're on room 3 now so hello okay and then we've got this so let's go over to room 3 that hello so that's working the go to room one shouldn't get any kind of message here but I am why am I so if you look at what's happening here I'm a refresh so as I'm connected to one connected to two connected to three it's not gonna reconnect me but I'm connected to all three channels now or roomed rather so what's actually going on here is since turbolinks isn't really refreshing the page I think we actually need to disconnect from the channels or rooms that we don't want to be in so I think I've figured this out and instead of just kind of coating all this out again from scratch because it was a little bit tricky I'm just gonna show you what I did and then talk you through it so first of all I Google around for API documentation for this action cable javascript library for awhile and didn't find anything now I might just be being stupid at the moment so if anybody has it send me a link down in the comments but otherwise I want to show you how I sort of deduced this and talk about the downfalls of it a little bit so what I'm doing is what we're doing here is we're creating a subscription every time we land on a channel or our broom and the problem is that the page doesn't reload and so we have always we're always keeping edge connect that we create so once we leave a room we actually need to disconnect and there's definitely a more fine-grain way to do this but what I'm essentially doing in this code right here is looping through all of the subscriptions and just removing all of them now the drawback of this is that if you had other connections that weren't related to rooms you're now disconnecting people from everything so this is a very sort of shotgun approach just eliminate all the connections and then create a new connection but let's take a look at how I sort of started figuring this out so I'm console logging the subscriptions and you can see here that this inside of it has more it has a subscriptions method on it which right now we have a single subscription and I basically just kind of dug around in the actual JavaScript console looking at these methods and it looks like you have this fine doll and you can probably just read the code in here somewhere right eventually constructor I don't know we can mess with that later I don't wanna get super in the weeds but basically I think what you would probably want to do is either find all or something like that based on some sort of query parameter or I don't know you could do a really complicated approach to this that would probably be a lot more efficient to what you're actually trying to achieve but there's a remove and it takes a single argument of subscription and so I just kind of thought well hey what if I just pass the actual subscriptions like all of the subscriptions to remove and that seemed to work I hope that's not too confusing honestly it confuses a crap out of me so for at least a few minutes so that is what it is let's let's try this here so we can vote or so we can all see it working in both windows so I'm gonna refresh everything so this is coming to be the full functionality that we wanted so let's go to room 2 actually let's make a new room and this is where we don't have sockets for the rooms yet so we can do that in the future blitz everybody go to room four let's chat so we have a firm to the left and that didn't work right here why did that not show up on the right okay so that's working try this again okay so it's working I guess I just had not refreshed something and it had some I had loaded this up with some bad JavaScript in a while I was testing so maybe I just had that loaded still sounds better room two or one and say from room one and so now it doesn't show up here but if I go here to room wine hi you know now now it's working so we really have a fully functional chat room at this point so what I want to do is just spend a little more time and kind of clean up the user interface a little bit and I'm gonna post the code on github so if you don't really want to follow along with this that might be fine if you do cool just stick around but that's what I'm gonna do now is just kind of make this look a little bit more real okay so what I'm gonna do first of all I'm gonna get rid of this hello thing here in this navbar I'm gonna just cut this and I'm going to just have the name of the room there then what I'm gonna do is go up to the above my form in this column three and the first thing I'm going to do is put a h1 and I'm just gonna call it well no I don't want h1 I just want to say logged in as current username let's see what that looks like I mean basically I want to find a good way to display that okay so what I think I'm gonna do here again I'm gonna go to my go to element --card --card body and actually gonna say logged sa small logged in as break and then I'm gonna do a bold tag and get the current user our username okay so let's see what that looks like okay that's a little bit better so what I'm actually gonna do is I guess I could do another nav right there right I mean why not so you could do nav bar it doesn't have to be just trying to think about how to make this look uniform ish so instead of card I could do div nav bar lights let's see what that does okay that's freaked it out I don't hate it actually that's interesting but then I'm gonna add a span here well let's see div let's call it div than that bar brand and see what that does okay so I'm not quite right um you know what let's just back this out to my card like that for now I'll keep it and I'm gonna fix the I'm actually gonna go ahead and do this I'm gonna say no outline okay and then in application and got as CSS down here I'm gonna do dot card dot no doubt line is border:none let's see what that looks like okay not bad not bad so now what what I'd like to do is add the no outline class to all of those rooms so down here we're gonna say no palette line see what that looks like okay so that's cool what I'd like to do though is say under this let's like that bold and let's make this small and say I want to say the number of members so what I'd like to do is say room dye users dot count and then say members so room needs to have many members has many users through messages let's see what that looks like okay that's no good so you can see here that this thing is messed up because it's it's counting the messages so what we actually want to do is say room dot users dot unique so now that makes sense right so you can see how many people are basically in the chat I'd like for this to be a safe room over here and then in I don't need that open anymore doing my okay so that room I think I should call that room card to be a little more specific room card let's see so we want to basically say I need to basically give this a class name and then we're gonna put the name in there and I don't want to be our tag in the span and then over here I'm gonna give this a spin with a class member count and then I'm gonna get all of this put that there okay so now I can do room card dot name font-weight:bold so I can actually get rid of the ball tag color black and let's do the dot member count and we'll do color maybe like seven seven seven and font-weight light okay so now what's that gonna what's that gonna do I don't need these bold tags anymore okay let's see what that looks like cool and so I also don't want this text decoration here room card so the whole tag is inside of a link right the whole card so I'm gonna say text-decoration:none and if that doesn't work I'm gonna throw important on there actually I'm gonna bump it in there on name and see if that does it no so I'm just gonna make that important and we're gonna see what happens I can make things look pretty good but I don't you always use the best CSS practices or know even more of a back-end person but I do like to make this kind of stuff I don't know why that's not working let's make it hovered I don't know let's see no but I really want to do oh it's because I need to actually get the a tag above it okay I'm being dumb let me go back so instead of this I'm gonna create a thing just above it it's gonna be that room link and then we'll just move that up there and let's try it without the important because it don't really like doing that okay and then let's add a class link to room class room link now let's see what happens nothing you know what maybe I need to do like and hover you try that that would be fairly sensible okay that's better so then I want to do background color a bunch of ease and I'm gonna do the border radius is 20 pixels see how this looks okay I'm gonna bump these guys down to the room card I don't think I should be putting those on the a tag I actually only want that on hover okay cool so what I'm gonna do here is say transition background color 0.5 s ease that should make that have a pretty smooth a little hover okay cool and I need to make the border radius on the room card so that it doesn't flash with those little angles that's pretty nice okay cool cool so we're getting there what I'm gonna do as well just make it so that the active room is a little bit more obvious somehow so let's see if we can do something cool with that so what do we want to do so we'll say and active background color let's see something kind of stark to begin it's a background color black color white I'm I need to do dot name and then we'll do a dot member count color may be easy rose okay and then what I want to do is say what is active in this case that would be the room card so here I need to say active class equals and then we'll do like ternary thing so we'll say at room equals equals room question mark and then we'll say active or then just nothing and then on the room card will say active class so see what this does so you should have like a black one that's pretty cool I don't need to print out active print that out there we go I don't mean that I like that that's pretty cool okay so now let's fix this add a new what's that let's fix the form because that looks like junk so how can we make that look alright so what I'm gonna do for that first wanting to open that so that would be wrong we know so that would be messages form no rooms for me okay so first of all let's just change this to be form group and then remove this from anything like that because I don't need anything there and let's make this in b3 you see where we're at okay I'm gonna make that BTN info to just give us a little bit of a change up as far as the colors go no I'm not I don't like that DTN outline primary is that how that's supposed to be written that's better that's cool nice let's do I don't need a placeholder probably what I do need is a something telling us that we're creating a new room so I'm just gonna make a pee bold create new room and with that you know what actually I'm gonna make this just say create new room create new room and then here we'll say placeholder room name and then we're just gonna say add that's gonna be add new ring I'm gonna get rid of this text and let's see what that looks like okay I don't hate that let's do you know what I actually want to do here I want to put this in a card now render form so we'll do div card is card body I think I'm gonna like this actually hmm don't hate it but it's like very tiny just do maybe a char tags above and below the wrong button so HR see what this does okay that looks pretty good add a new room room name so definitely have a you know sort of monochromatic style one on here um let's see what else can we do to make this look good what is this column called so I have a column here so let's just call this room and then rooms sidebar maybe so what I'm gonna do here is just border right one pixel solid and definitely taking some inspiration here from facebook messenger okay so that looks pretty good I think that looks pretty cool actually so this over here looks kind of janky first of all this is really janky with the its scrolling past this thing and you can't see or there's this sort of layered thing I want to get rid of the scrollbar so that's happening because I have a mouse plugged in but I still I just don't want to see the scrollbar they only if I'm scrolling or something like it's sort of native Mac behavior all right so I'm gonna start by just eliminating eliminating my scroll bars I'm just gonna paste in some code from the web and this should just axe the scroll bar okay and now we can see over here on the right we do not have a scroll bar anymore also doesn't scroll super well there goes okay so it looks better it's less overlap we need to go down to our chat box and we're gonna say background color white border top one picks solid ee-ee-ee-ee see what this looks like so what I want to do actually with that thing because that does look better obviously but I want that to go all the way across so let's see how we can make that happen so we actually want to large in left - 15 pixels let's see how wide it is now it's not wide enough and that's because we are subtracting 15 pixels off those right there so now we're in business okay so let's go ahead and change that up so we're just gonna make this a hundred percent and then we're gonna margin left - 15 percent let's see what that not percent pixels excuse me and it looks like that should do the trick for us okay so what we also need to do is on the bottom of so actually what we would like is the chat room so the chat room does the chat room contain the chat box that is the question so div I need messages exist outside of the chat box so we don't want that to go all the way down so if when you height calc 100% will - a hundred pixels where's that get us does that do anything yeah the box is there so actually you know what I'm noticing is I need to I can use this messages in this manner so let's get the heights to be right or close anyway let's see like where are we so let's bring it on down come on down is that gonna put me right at the thing that's pretty weird okay so we'll come back to that let me actually try to so chatroom messages and then in here I'm gonna get that again I don't think I've ever done that before okay so let's try it out with the messages and see what that does that's odd you know that's the whole page scrolling now I guess it's because it doesn't have a height maybe let's try putting a height on here okay so now the whole page does scroll but you can also see if you get in here just right you can see that scrolling so you kind of have to be on top of an element which is kind of weird so I'm gonna actually kill the overflow why on the whole page hidden let's see what that does so now if I come over here okay so it all works the way you would expect now so that just kind of Scrolls inside there but you can see we have a problem there at the bottom so that was supposed to be glued to the bottom why is it not at the bottom of the page weird why don't you set that to minus 10 pixels okay where can I do that at down here in the chat box minus 10 pixels normally I would try to worry about why that's happening but right now I'm really not concerned I just want to kind of wrap this up so now what we need to do is figure out how to get that height to not be so tall actually that's not right what I need to do is give myself padding at the bottom of like 100 pixels maybe padding sorry padding-bottom 100 pixels let's see what that does nothing okay so I've played around with this for a minute and it looks like I need to set the padding bottom on messages here to 200 pixels or something like that so that we can actually scroll up to see the latest message because everything else was getting cut off down there so I'm going to add that on my messages object object my message is ID here so I'll say padding-bottom 200 pixels so now I can scroll all the way to the bottom what would be great is if it started out already scrolled so I need to investigate how to do that I think I'm gonna have to make another video to kind of work a little bit more on some interactions here because this is getting really long and I just want to do one last little bit of cleanup so yeah let's do that really quick let's just wrap up the styling and just call it a day okay so the last thing I want to do is deal with this navbar thing up here so I want to say where are we so I've got my chatroom nav bar I'm gonna get rid of this BG light and in actual fact we need to get rid of this in b4 thing so now we can see that that looks like it's just scrolling there but what I want to do is first of all so where are we chatroom and then we have nav bar so on so I'm gonna say right here I'll just do dot nav bar and we'll do border bottom one picks solid and the same thing we've been doing and let's see what that looks like okay so we can see everything just scrolling straight under that way which is nice we have a little bit of a gap here and I'm gonna fix that and I suspect it's gonna be the same kind of deal - 15 pixels and let's see how wide it actually is I think this is just because this is in a not in a div that has padding basically so I'm gonna do with calc 100% plus 15 pixels let's see what that does not what we wanted maybe I need to go a little bit more even doing anything I don't know it's not doing any thanks being clicking the right spot okay so yeah that's going out so I can do 30 you can see that the very bottom of the screen if I go past 30 that thing jumps on the screen so I'm just gonna do 30 it is exactly right so plus 30 pixels and now this is starting to look like a real chat application to some extent let's go ahead and do one thing here I want break this out we're gonna make this in bold okay and then last I'm just gonna do we're gonna do a small gonna do another yard oh I'll see what this does I need to make that at room that may not look good or may take up too much space then they mess up our work there no I think it's fine kind of break it out of that actually and get rid of the br tag and put that in in parentheses well let's just do it like that three minutes weird okay I can dig that I think I think that looks cool so yeah that's about it for this one actually so I'm gonna kind of study on the interactions here and the user interface I think this is a slick looking a little thing I mean obviously it takes a lot from the messenger design we can make it even better I'm a mess around with it a little bit more on my own and whatever I end up doing I will put on the github link which you will find in the description so if it looks a little bit different don't worry about it you can just kind of take a look around and see what's going on but that's about it for this video if you made it this far thank you so much for watching and I hope you found this helpful and I will talk to you next time
Info
Channel: Techmaker Studio
Views: 13,287
Rating: undefined out of 5
Keywords: action cable rails 6, action cable chat, action cable, ruby on rails 6, ruby on rails projects, rails 6, actioncable, actioncable rails 6
Id: s3CmHhDjuWc
Channel Id: undefined
Length: 110min 1sec (6601 seconds)
Published: Fri May 01 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.