What's up guys? This episode is the beginning of a series where we're going to be building a chat application using rails 5 and ActionCable. What we're going to try to do is build something a little bit more robust, like Slack for example. We're going to try to build an application where you log in and you see all the channels on the sidebar and those in real time update when there's a new message and all of that stuff. This is going to be a lot more complex than the DHH posts example that we saw with the ActionCable example chatroom that he built before, and it's also going to be more complicated than the notifications thing that I did which is just a tiny piece of your website. This is going to be the core-focus of the application, so we'll have the sidebar with chat, it will get updated in real time. We'll also keep track of new messages and show you where you last read that channel at, and all that stuff. So it's going to be interesting and there's going to be a lot to it, but we can break that up into a handful of episodes, and we'll go tackle all of those and we'll go build an actual chat application so you can get the idea of what it takes to build this bigger applications with ActionCable.
Without further ado, this episode we're just going to dive into building out all the foundational stuff at a high level, so we're going to talk about building the users, the channels, the connections between users and channels so next time you log in we remember where you were at. We'll talk a little bit about recording when you last read, we'll do maybe the basic set up for bootstrap and stuff like that, but we won't get into ActionCable until next episode. If all this is new to you, then keep watching. Otherwise you can skip forward to the next episode if you want to dive into the deep end. Without further ado, let's keep going. First thing is first, let's make sure we're using rails 5. This is officially been released now so we can dive into that and we have the latest version installed so we can go and create our chat application so we'll say rails new chat, and once that's installed, let's cd into chat, let's open up our gemfile, install a couple gems.
gem 'bootstrap-sass' gem 'devise'
class Chatroom < ApplicationRecord has_many :chatroom_users has_many :users, through: :chatroom_users has_many :messages end
class ChatroomUser < ApplicationRecord belongs_to :chatroom belongs_to :user end
class Message < ApplicationRecord
belongs_to :chatroom belongs_to :user
**user.rb** class User < ApplicationRecord devise has_many :chatroom_users has_many :chatrooms, through: :chatroom_users has_many :messages end
Editing those views with devise is really simple but because we're using bootstrap it's also something we have to go customize to fit with the bootstrap html for the forms and stuff, so actually this past weekend, one of the Gorails community members, Andrew Fomera was working with me and we we're kind of poking at the idea of what if you could just generate the views for devise that were already precompatible with bootstrap? Because both of us recognized that we would go do it once, and then go copy and paste it from another application. So he took advantage of that, and built a gem called devise-bootstrapped, which you can install in your gemfile, and this is super nice because you can say: Let's run bundle to install it, rails g devise:views:bootstraped, this will install all the views for devise but with tweaks for bootstrap so they look nice there, and then once you're done with that, you can actually remove it from your Gemfile so you don't have to keep it around, because chances are you're never going to run those generators ever again, so voila, you're done, and you have nice views, and you can see that if we now go edit settings, this is now automatically styled with some basic bootstrap stuff and even centered on the page as well, so this is pretty nifty and gives you a good starting ground for going and modifying your views. Now the view we're specifically looking for are the registration ones, and we're not going to modify the sessions to allow you to log in with either an email or username, but you can also do that, there's a link in the devise wiki for how to do log in with email or username and it's really simple, but you can go do that, but if you're really interested, let me know, we can do an episode on it, but the instructions in the wiki are really simple and of course are going to be up to date whereas the video might get outdated. So let's go edit this view, and so now we have this email field here in a form group. We can change this to a username in both cases, and let's also say that it's a text field, and our email should not be autofocused, so with that, we can take this and also put it in the edit so that you have the ability to modify both of those and there you go, so maybe you don't want the user to edit their username after the fact. That's up to you on how you want to control that. We're going to allow it just to keep it succinct. That's the view portion of this, now we're going to go edit the application controller to add the permitted parameters. The permitted parameters in devise have changed a bunch over the years, and the ways of doing that have kind of adjusted into this version four that's compatible with rails 5 has changed once again, and so it's always good just to be able to go look this up in the README and make sure that you're doing the right way. So for example, we're just going to grab this snippet here and paste this into our application controller, and so this is basically saying: Well if you're in a devise controller, then we'll run this method, and this is saying: Let's modify the devise permitted params, they have the to call it a sanitizer. For the sign up action let's also add in the username key, and we can do the same thing for account_update, and that way we'll have that available to us when we update our account. So this is basically just inserting that item into the parameters that are allowed and you don't have to specify email and password and password confirmation for any of this stuff because it's already kind of assumed that you're going to have to have that anyways. So with this installed, we should be able to go and create a new user once we log out of this one, with a username. Now you see "Gorails" at the top, because it did get the username and save it to the model so that is the only two things that you need to modify with devise if you want to add that in. We're getting pretty close to having all of our foundational stuff set up. The one thing left is really to make the chatroom sidebar, so we want to have the ability to see all the chatrooms on the side, and then the main content of the website will actually be a view of that chatroom that you're actively looking at.
Because we've already covered quite a lot in this episode, I'm going to split this into two parts, and the next part will be building out that layout, and then also adding the join and leave buttons, so you can join and leave those channels, and once we have that ready, we'll be ready to go in building out the message functionality in our app, so until then, I will talk to you in the next episode. Peace ✌️
Transcript written by Miguel
Nice job. Look forward to #2.
Can you post the block of modified navbar code that you inserted into application.html.erb? I wasn't able to catch all of it on the screen to see the changes made.
Thanks! I can't get the username to display in the navbar. The line where you define current_user.short_name throws an undefined error for the 'short_name'. I couldn't find that defined explicitly anywhere else in the program.
It should be current_user.username.
https://github.com/gorails-... You can find the code for the layouts from the episode there.
If you're wondering short_name is probably a method on the user.rb file in the model folder and it's probably setting short_name to whatever the users first name is. But like @ineptsoftware:disqus said, if you change it to current_user.username or current_user.email it should work :)
This was great Chris (edit sorry wrong name lol)! Thanks! I can't wait until you dive into the actual ActionCable. What is the ETA on the second episode?
Hey im new to rails and still getting quite comfortable with Ruby. But I seen that version 5.0 of Rails is out. How do I upgrade/install it? Thanks!!
You can just run "gem install rails" and that should install Rails 5. I'll be doing a screencast on upgrading an existing app to Rails 5 pretty soon.
Hey has this up yet? @excid3:disqus
Haven't recorded that yet, it kinda slipped my mind. Let me get on that this week!
How are you getting those icons like padlock in the text_field?
Hey Chris! I know I'm late to the party...haha! I found a way of adding custom fields with Devise that I like...
added_attrs = [:username, :email, :password, :password_confirmation, :remember_me]
devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
devise_parameter_sanitizer.permit :account_update, keys: added_attrs
This makes it super easier to add additional fields in the future. Anyway, just a quick tip! :)
thank you for the tutorials. I was wondering if you could make a tutorial for setting up MacVim just like you have? I have tried myself, however, I can not seem to figure out how to do it.
Hi, this is a great tutorial so far! However, i'm having some issues near the end. After I add the Devise permitted parameters to the application controller and I try to sign up, I can no longer access the site (even after refreshing and trying to go back to the main page. It gives me a NoMethodError in Chatrooms#index. It says "undefined method `public_channels' for #<activerecord::associations::collectionproxy ="">
Did you mean? public_send" and that the error is from application.html.erb. I replaced my code in that file with yours from the github repo, but i'm still getting the same error. Can someone please point me in the right direction? Thanks!
First of all wonderful tutorial. I have a question, please see if you can help out,
I have a question model and a conversation model, a student asks a question and based on that question a teacher chats with that student. Please note only one teacher and one student are allowed in conversation per question. A student can only ask one question per email address. Now we wanna introduce a live chat support system for our support team to be able to chat with students. Now this chat room should be unique to each question and any number of support users can be present but only one student. How should I go about creating models for chat room based on your tutorial?