Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

Admin User the lazy way?

I've built user logins (plus relevant associations) for a site, and the next step is to create a page that only the site owner can post to (but users can read).

I've used the Sorcery gem for building user logins, which has worked well so far (Devise seemed to be a bit TOO bulky and OTT for my needs - hope I don't come to regret that decision!).

From briefly reading a few forum posts about how to create 'admins', I had an idea that I'd like to run past people before committing to it:

Rather than creating a 'true' 'admin', why don't I just make sure the website owner is the first person to register on the site, having set permissions and associations based on a user_id of 1? I'm not sure how exactly to go about that yet, but I'm sure it wouldn't be very difficult?

3 Answers

Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

If you want to do it your way and you're sure you only want one admin user (with id of 1), then it's a simple before_action in the controller with code like "redirect_to some_page_path unless current_user.id == 1" for selected actions available only for that user. Brandon's link is very cool, I will surely build a training app for myself to try to implement it. If you want something heavier, then check out Pundit gem.

I'm SOOO tempted to go down this path, because it would be so much easier and quicker than learning and implementing the enums system. Try to talk me out of it, please.

Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

You can also just add the admin field to your users, boolean, with false as default and make a before action like "redirect_to some_page_path unless current_user.admin == false". And modify this field only in the console, don't put it in the form and strong params ;)

I can't get this to work. I've put the following in the private section of my Materials controller:

def user_id_1?
    unless current_user.id = 1
      redirect_to materials_url, notice: "You have to be an admin to do this"
    end
end

And this at the top:

before_action :user_id_1?, only: [:new]

But it just doesn't work. It doesn't return an error, but instead just stops ANY user from doing the 'new' action, rather than just the user without an id of 1.

And yes, I have checked the user id's of the users I am testing this with.

Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

Try this

current_user.id == 1

:)

Ok, so the user id of User.first wasn't actually 1; it was 6. And I couldn't change it permanently in the console (a bit of googling says that Rails prevents this).

I tried destroying all of the users and then creating a new one but, as expected, it didn't give the new user an id of 1 (it was something like 13).

So, I'm using User.first.id instead:

In the application controller (because it's quite a handy method):

def first_user?
  unless current_user.id == User.first.id
    redirect_to materials_path
  end
end

It works. The key really was finding out that you can't change a user id without forcing things, but it sounds like that might be a bit dangerous, so I opted for this instead.

I think I need to go back to reading up some more and adding to my 'core' knowledge - I'm just firefighting now without REALLY understanding what's going on.

On the positive side - look how far I've come, Maciej! :-) Remember helping me set up my environment only a few months ago? Now I've setup my badass dual-boot laptop and have a couple of apps up and running :-) I do think I need to read another book though.

Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

I think you'd have to rake db:drop, rake db:create and rake db:migrate to reset the id counters to start from 1, but this wipes out all your objects in all tables. And yes, I see a lot of progress :).

Brandon Barrette
Brandon Barrette
20,485 Points

I'd read this blog post about the introduction of enums in Rails 4.1:

http://www.littlelines.com/blog/2014/04/21/fun_with_variants_and_enums_in_rails_4_1/

It gives you many helpers to ask

if @user.admin?

Yes, that 'enums' thing is VERY cool! I might implement that into my current build.

Brandon Barrette
Brandon Barrette
20,485 Points

Enums work very nicely with Pundit too.

And the can be used basically as a state machine too (with some more code). Last time I checked the state machine gem wasn't playing nice with Rails 4

Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

Yeah, you have to use aasm instead.