Running the Comment Generator and Installing the NoSQL Redis Database in Rails 5
In preparation for ActionCable, in this guide we're going to generate the Comment model, configure the foreign key database relationships, and install the Redis NoSQL database.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

This is going to be a very exciting section. I had a lot of fun planning this one out and when I went through some of the pre-filming and testing some of the different components out. It's a very cool feature I think you are going to be excited about this one.

So I'm going to drag over our ActionCable live data feature and let's pop it open and click start and let's scroll down. We are going to cover what ActionCable is how to build out forms for comments. We're going to build out the comment model and controller. We're going to integrate users and associate them with comments, we're going to integrate the Redis database. We're actually going to do that right here and then we are going to customize the views. So essentially at the end of this section, we're going to be able to add comments on our blog posts but that would be an easy thing you could go do that yourself right now. What I want to do is add comments that will actually pop up on the screen without a user having to even refresh the page. So I think this is going to be a pretty cool thing to build out. Now there are a couple things that I want to mention before we get started. One I'm going to give you access to the Redis gem. You already have access. I'm going to give you the link to the Redis gem so that you can come and grab that. That's going to be the first thing we do. But the other thing I want to add ActionCable is a brand new feature. This is one of the most anticipated features of Rails 5 but also because of that anytime you have something that's brand new there's kind of a lag in the time where there are resources, blog posts and guides written about it. So one thing that I did before I started building this out because I've never even integrated ActionCable in any production apps yet it's simply too new and most production apps I have at the moment are all in Rails 4 which don't have access to ActionCable. So I wanted to include a link to a guide I found incredibly helpful and it's not exactly what we're going to be implementing. They show how to build a chat application using Rails 5, ActionCable, and Devise and this is by Site Point. I will include it in the resources so you can check it out because I definitely went through it a number of times to understand how it works and to understand what we could do with it. And they did a fantastic job in building this out. So I always whenever I lean on someone else's guides or anything like that I always want to include them, one to give credit. But then also to show you what my process is. I think one of the things that I get frustrated with instructors and other developers is when they want everyone to think that they are just so good at developing that they don't need to rely on any guides or tutorials or anything that they just somehow magically know everything and know how to build any kind of feature that simply is not the case.

You need to be able to rely on guides and tutorials and all kinds of resources in order to build out advanced features. That's something that I do. I spend and dedicate a certain percentage of every single day trying to learn something new. And this is one of the things that I came across actually back in the fall. I went through this guide and bookmarked it because I knew I wanted to build a Rails 5 course and I thought this would be a perfect feature for building into it. So with all of that being said lets actually get started on building it out.

First thing I'm going to do is grab the Redis gem. Now Redis, if you've never used it before is kind of like a little database. It is a database but it's not like Postgres, it is incredibly fast but it is considered a NoSQL database which means that you would not use Redis in order to perform tasks such as connecting two database tables and running join queries or any of the kinds of things that are needed in a relational model. What Redis is, is it allows you to have a key-value persistence storage set up. So essentially what you can think of this as being is the ability to persist hashes because at the end of the day that's really what Redis is doing is it is a key-value database and I definitely recommend for you to open up the documentation for Redis and go through it and see some of the cool things that you can do. It's a very powerful tool. We're not going to actually have to use it in terms of communicating directly with it. ActionCable uses it and we're going to be able to leverage it as a data storage system but it's not something that we have to spend a lot of time working with.

So you open up Sublime Text and the first thing let's go to the terminal. We're on the master branch do

git status

No changes here. So I'm going to say

git checkout -b actioncable

This is going to be our ActionCable branch and now that we have our branch set up let's go into the gem file. And if I scroll all the way down right underneath that last Twitter gem we can add Redis. Now, this is pretty cool. Just pause really quick look at all of the various libraries that we brought in throughout this course. We brought in Friendly_id, Devise, Bootstrap. We've built our own gem Petergate Font-awesome all kinds of things so you should definitely be proud about what you've done and accomplish through this course because these are not trivial things to add. Implementing things like Cocoon is a very cool feature to have in your application and you've done it in a pretty efficient manner of time. So I'm going to run

bundle install

This is going to bring in Redis for us and with the way that ActionCable works we're really not going to have to do a ton in order to actually get that working. Because ActionCable comes and it ships with Rails 5 we simply have to activate it and configure it.

Next thing is let's come into our app and go into assets, Javascript's and our application.js file. Now right above turbolinks and even copy one of these and say

require cable

and that is going to simply let our javascript file know that we are going to be using ActionCable for this and I want to also show you another file so if you come in your javascript's directory and click on cable.js you can see that essentially what this is doing by us saying require cable it's saying that I want to bring all of this in which is going to bring in ActionCable and then its going to bring in all of this code. Now if this does not make a lot of sense that's fine. This is pure javascript code here. That's essentially saying that we are running this app and it's creating an instance of this app. Just don't let some of these terms scare you away but whenever you see javascript written like this where it starts off with the parens and then says function. This is an immediately invoked function which means exactly what it sounds like, it is immediately invoked. So whenever this file loads it is going to start all of this which essentially just says I want to create a consumer which means that we're creating an instance of ActionCable. That's all it is. Now we're also requiring tree ./channels. Now that is a directory in here. It's empty right now but we will be building quite a bit of code and adding it inside of there. So that's a good thing to keep in mind as you know how that side of it works. So now that we have all of that the next thing we need to do is actually create our comment resource so I'm going to say rails g resource so this is going to be using the resource generator. And the reason I went with a resource generator is because I don't want views for comments. We are going to be building our views manually because we're going to be putting them on the blog page and that kind of thing so I don't want views generated, but I do want a controller and I do want a model with some attributes and that's where a resource comes in very handily. So I'm going to say `rails g resource and call it comment

rails g resource Comment content:text user:references blog:references

and it's only one attribute in terms of data. So it's going to have content:text but then it's going to have to be owned by a user so it's going to be user:references and then blog:references. So essentially what we're saying is that this is a comment this is a new class and it's going to have a controller and a model and it's going to have one column in the database specifically for content data and that's our content column. And then it's going to be connect it to users and to blogs which means that a user can have many comments they can post many comments and a blog can have many comments as well. So if I hit return. This is going to run the generator and assuming everything there works this is going to give us what we need and then we can run rails db:migrate and from that point on we will be able to be good with wiring everything up. So it looks like everything there is good. I'm going to now run

rails db:migrate

and now with this running this should update our database and we can go into the model files. Looks like we have one little issue. Oh and this is something I'm actually glad that this one came up. You see where it says PG: : ConnectionBad could not connect to server: No such file or directory. A little piece of knowledge for knowing why this happened in between the last video and this video. I got a new MacBook Pro and I'm actually filming on it. Everything here pretty much looks the same but I did not start up the Postgres app so I'm going to open up the Postgres app and assuming that works then that should give me what I need. So let's see if we can run this again and there we go. So if you ever see an error like that where it says

PG: : ConnectionBad: could not connect to server: No such file or directory`. And it says `is the server running locally and accepting connections

That means that you probably do not have your server running and it's because I have the Postgres app started so it starts by default but that does not apparently happen when you get a brand new computer. So that's a reason why. Now let's open up our code and let's go into our blog model so we know that we need to wire our blog up to comments so we want to add a has many so I'm going to say

has_many :comments, dependent: :destroy

And so what this is going to do is it's going to say that a blog, pick out any blog on the site it has the ability to have many comments on the page and I'm also going to add in a dependent destroy. And I am probably one of the worst at spelling dependent so I'm going to paste that in and see if that is right. OK. It appears to be right. We'll see, if it throws an error I'm going to know right away. And so I'm going to copy that and if I open up the user.rb now we know that we want a user to have the ability to have many comments now this kind of goes to something we talked about earlier on in the course when we talked about "has_many" belongs to and knowing when to use one versus the other. Now this is part of the reason why I love Rails is because I think that it makes perfect sense in how this is set up for example as a user, think of just a real live user one of your friends or another developer going to your site reading when you read your blog posts and writing a comment and then another person going in writing another comment. That is one blog post two users and then multiple comments. So what that tells me is that a user has the ability to make a comment. Now if that user comes back and sees some additional comments or you made some changes on the blog they should have the ability to make more comments on that blog and not just that blog but any blog on your entire site. So if you want that behavior which is pretty standard, then you want to say that a user has many comments now dependent destroy what this means is that say that you have a user who goes into their account and they delete their account. That means that all of their comments are going to be deleted and you want this because if you don't put something like this there what could happen is if the user goes in and deletes their account and you're going to have what are called orphan records in the database. So you might have some situation where you have all these comments that don't have a user if you try to do something like call comment.user. name to get the user name but that user no longer exists in the database then you're going to get a nasty error message. And so it's important to do dependent destroy for has_many relationships in many cases just to ensure data integrity. Same thing with blog posts. If you ever go and you delete a blog post you made you want all the comments to be removed from there as well because it wouldn't make any sense for a comment to exist without a blog or a user. Now that being said let's open up our comment models.

So if you go to app/models and then go to comment you can see that by default because we use the references flag in our generator that it automatically told us that a comment belongs to a user and it belongs to a blog. And one last thing I want to do before we end this guide is let's open up the rails console. And let's test out this ability so I'm going to make sure that I have a user. So I'm going to say

u = User.last

store it in a user variable. So yes I have a user right there it's me and now say that I want to make sure I have a blog so I can say

b = Blog.last

And there we go I have a blog right there as well. So have both of these and I have them stored in variables. Now what I should be able to do is I should be able to say

Comment.create!(user_id: u.id, blog_id: b.id, content: "Some comment content")

because remember we stored the user in the variable u and then a blog underscore ID and stored in the variable b. and then we have some content. So just we could put some comments content. And now if I create this should work and it looks like it did. So now if I do this I could say

Comment.last

It brings up that comment and now I should have the ability to see who made the comment so I should be able to say

Comment.last.user

and it brings back the user that did it. And I should also be able to see what blog post it is on. So if I do

Comment.last.blog

it shows me that OK this comment belongs to this blog. So that is all working perfectly. Now if I type

get status

see all the changes we made I can

git add .

and say

 git commit -m "implemented Redis library and created comment generator" 

now I can say get push origin ActionCable and this is all going to get pushed up to the repo and we're going to be ready to move on in the next guide we're going to build out our comments controller so I'll see you then.

Resources