Introduction to Devise and Admin Roles
Hello, the internet. My name is Dean, and welcome to probably the last tutorial video that I'm going to be getting out tonight. This one's for setting up Devise for user accounts, which means we're going to be setting up a sign-in, a sign-out, and a sign-up link. And we're also going to create a basic scaffold and associate it with the user account so that you can see who posts what. And finally, we're going to add in an admin boolean so that you can see if a user is an admin so that you can delete a post if you don't like it if you're on an admin account. So, that's a lot to cover, so we're just going to jump right into it. We're going to start off by doing rails g. Actually, we are going to start off by just adding in Devise. We'll focus on the user accounts first, and then we'll go from there.
Installing and Configuring the Devise Gem
So, for this, we're going to come into our Gemfile, and we're just going to type gem 'devise', and then we can come back to our terminal and just run a bundle install.
And assuming I stopped Spring appropriately, all of this should work, but let me just run this one more time just to make sure.
So, now that that's all cleared up, we just need to run a rails g devise:install. That'll run the basic installer for Devise, and it should give us a little bit of a pop-up that says, "Hey, do these five things." or four things.
So, we can skip the first one. That one's not really important. We do need a root to, but we'll set that up in a bit. Let's copy these the notices and the alerts, and let's add them into our views. So, for this, you can either come into your application.html and paste them above the yield tag, or you can be a bit more civilized and create a new file under layouts and save it as _alerts.html.erb, and just paste those in there, and then come into your application.html.erb file and just do a render layouts/alerts. It'll have the same effect, but it kind of changes it from like two lines down to one line. And then if you end up styling the alerts a bit more and, you know, making them a bit more involved, then you only have to worry about this one line clouding up your application file.
And the last thing it's telling us to do is to generate the views, but first let's make sure we generate a user account. So, for this let's do rails g devise user. That'll create our users, and then we'll just type rails g devise:views. And what that's going to do is it's going to generate all of the views that we can then go into and edit and remove and change how we feel.
So, for this, this is the registrations edit. So, like if you go into edit your user account, this is the page you'll see.
Setting Up the Home Page and Root Route
Um let's go ahead and I guess just do a basic controller. So, say rails g controller pages home. So, this will just give us a home page. And then we can come into our config/routes.rb and change this from get pages to root to: 'pages#home'.
So, now that all that's done, let's do a rails db:migrate. And then we can start the server with a rails s command.
So, assuming all of that worked as we expected to, this shouldn't blow up horribly, which it hasn't. That's always a good start.
Uh let's go to our pages/home. And we can get rid of this find me in wherever.
Implementing Authentication Links
And let's create our first link. So, for this we're going to use a bit of Ruby code. We're just going to say link_to 'sign up', new_user_registration_path. And that should work. So, we can click on sign up. We'll do a email, and as you can see here I have 8 billion of them. We'll just do [email protected] with the password of password. And by default, all of these passwords are encrypted, so you don't have to worry about that.
Now let's add in a link to sign out. So say link_to 'sign out', destroy_user_session_path. And for this one, if we just leave it like this, this link actually won't work. We can click sign out all day long, but it'll just throw an error. And the reason for that is after the destroy_user_session_path, we need to then say method: :delete. So we can refresh, hit sign out, and you've signed out successfully.
The last thing to do is to give us a way to sign back in. So for this, we'll say link_to 'sign in', new_user_session_path. And you don't need to give this one a method, this one will work just fine. So now we can click sign in, and type in our email and our password, and we can hit log in, and that's working.
Conditionally Displaying Authentication Links
So now let's do a quick check to see if the user's logged in. If the user's logged in, we kind of only want to show them the sign out option. So let's say, um, if current_user. So this just checks if there is a current user, then it'll do whatever's in there. So we'll grab these two. And we'll say if there isn't a current user, do those, and if there is a current user, then only show the sign out. So now if we refresh, we have the sign out option. And if we're signed out, we can sign in. And then it shows us the sign out option again.
So that's working as we would expect it to. You can obviously style this a bit more if you want to, but that's not really the point of this tutorial.
Adding an Admin Attribute to the User Model
Um, let's do the admin stuff real quick. So, for this we just need to do a rails g migration add_admin_to_user, and then we'll just say admin:boolean. So, that just adds the boolean into the user and then we can find our DB folder and our migrate folder and then we can go into the add admin migration and at the end we'll just say default: false.
And then if we type rails db:migrate, that'll hopefully add in the migration. And if we start the server right now we'll see that we um by default are not an admin but we'll just change that real quick by going into rails c. And we'll say @user = User.first. And as you can see the user is an admin and it's set to false. So, let's just do @user.admin = true and then @user.save. And then you can hit control D to exit out of the rails console.
Scaffolding a 'Post' Model with User Association
So, now our user account is an admin and we can generate a scaffold. So, for this we'll say rails g scaffold and I called this Reddit so, let's just I don't know give it a thread. And each thread has a title and a body of type text and it'll also take a user:references. References, that looks right.
The name thread is ar- all right, okay. Well, guess we're going back to the basics. This is why you don't improv. We'll just call it uh rails g scaffold posts and keep the rest the same.
As usual we'll come over to our assets, our style sheets and we'll delete the scaffolds.scss file cuz nobody likes it. And I think that's about it. We can now type rails s to start the server and refresh.
Uh and we forgot to run our migrations. So, we'll do rails db:migrate. And then we'll type rails s again.
Associating Posts with the Current User
So, assuming all of this is running, you can see that uh we don't have a link there. So, let me change that real quick. Uh we'll just say home.html.erb. And below these, we'll just do uh <%= link_to 'posts', posts_path %>. There we go. We can click on the post. It takes us to our post scaffold. So, here we can create a new post. And the form has the user field for some reason. The reason for that is when you hit the references, it kind of generates this by default. We don't want that though, cuz we want the user to automatically be selected.
So, we'll come into our posts and our form. And we'll delete the user ID field. Just that whole thing can go away. Now, we also need to get rid of it in the controller. So, we'll come up to our controllers and our post controller. And we can get rid of this user_id. We don't need that. But, before we run our create, we should do a @post.user = current_user.
So, that's just going to associate the current user with the @post.user. And then it'll say, if @post.save. So, right here it's saving it. And before it's saving it, we're just saying, "Hey, set this post's user to be the current user." Which means we have to run an authentication to make sure that we're not saying, you know, add this user if no one's signed in.
So, for this, we'll say before_action :authenticate_user! except because we don't want this to run if it's the show page or if it's the index page. So if you're just looking at a post, it doesn't matter if the user signed in and if you're looking at all of the posts, it doesn't matter. The only time it matters is if you're in the new or the edit or the update or the destroy.
So now if we refresh the page one last time and say hello world, I am me and then hit create post. You can see that the post was created twice. And that's because we have the alerts set up in the layouts and we haven't deleted them from the actual show page rendering. So we can just delete that notice and then we're good with that.
We have the title, we have the body and we have the user. Let's go ahead and change this user to give us something meaningful. So instead of @post.user, we'll say @post.user.email. And that gives us the user's email. We can take this a step further and say @post.user.email.split and then inside of that pass the @ symbol. So we're splitting it at the @. And then this splits it into basically Dean and then the @ gets the split and then example.com.
So this is the first element of the array. So if we just type zero in the brackets, we get this part. And then after that, we'll say .capitalize so that we get a fancy looking fake username out of this. Obviously, this isn't going to be a unique username. This is mostly for stylistic purposes.
And then just because I like showing it off, you can also grab this whole email thing and put it inside of the user model. So we'll just come down here and we'll fix our indentation and we'll say def username return self.email.split('@')[0].capitalize. And if we come over to this, we can just change this to user.username. Which gives us the exact same result.
Restricting Post Actions to Admin Users
Uh the final thing will be to come to our index page and make sure that the destroy and the edit only show if the user is an admin. So for this, we have to come to our posts and our index page. And right here for the edit and destroy, we'll just say if current_user. So we're checking if the user's logged in. And current_user.admin. I think that might need a question mark, but we'll try it without the question mark. And then we'll just call the end right there so that this doesn't blow up.
So here you can see that you can edit and destroy this post, but if we go to our home page real quick and sign out and then go to our post page, you only see the link to the show page. So obviously a lot of this is customizable, but this is kind of the gist of how uh devise works for all of this.
Conclusion and Next Steps
If you want to take this a step further, you can follow the bootstrap setup guide. And if you set up simple form to run If you set up simple form to run with bootstrap before you set up devise, then the devise forms will all get styled with bootstrap.
That'll I'll probably cover that in a later tutorial when I do like a whole project from start to finish. Cuz that's generally what my workflow is I is I set up bootstrap and then jQuery and then simple form. And then devise and at that point I start actually building the application.
But uh for now, thank you for watching and I'll see you in the next video.