Skip to main content

How to prevent access to a group if user isn't a member?

Rails • Asked by Alan Reid

Hi all,
I have user groups setup on my app using the code below...

class User < ActiveRecord::Base
  has_many :user_groups
  has_many :groups, through: :user_groups

class Group < ActiveRecord::Base
  has_many :user_groups
  has_many :users, through: :user_groups

class UserGroup < ActiveRecord::Base
  belongs_to :user
  belongs_to :group

All is working as expected, users are assigned to a group, and can access the data for that group. I have come accross an issue where any user, can access ANY group. Obvioulsy this is not good haha.

Can anyone recommend how i would go about preventing access to a group if a user is not a member of the group they are trying to access.

I was thinking of using a before_action and using it there and other controllers when needed.

FYI, i also have products assigned to groups so have a URL structure (below) which measn the ID variable for the group changes, not sure if i could just make that stay as :group_id maybe?


Any help would be much appreciated. Thanks in advance.

Hey Alan,

I think the before_methodis the way to go here if all you're needing to do is see if the current_user is part of the requested group.

  def authenticate_group_access
    unless current_user.groups.pluck(:id).include?(params[:group_id])
      redirect_back fallback_location: some_default_path, notice: "Silly bloke, you can't do that!"

There may be a cleaner way to handle the changing group_id param, but the few times this problem has popped up I break the rails convention (gasp!) and update my routes to use :group_id instead of :id since you have nested resources. Really I kind of prefer the more explicit convention of :model_id over the more ambigious :id for this very reason. It does require you to pay a bit more attention to your links and such.

Had to convert the parm to an int using .to_i but otherwise that worked well. However, as I had set the route "slug" to group_id. and I then had the issues that my nested routes were given the param group_group_id dammit! haha

Any way, I stuck the nested resources inside a member do and a little tweaking of the paths, everything seems to be working as expected. Maybe not the cleanest solution, but sometimes I do feel the strictness of Rails can be a negative.

Haha, yeah it can be fun trying to figure out some of the little nuances...

For your routing, check out scopes which will let you do things like:

namespace :admins do
  scope module: :locations do
    scope ':location_id' do
      resources :discounts

Which would give routes like /admins/:location_id/discounts and /admins/:location_id/discounts/:id/edit

As always so many ways to get stuff done. I will check out scopes later this evening.

Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 24,647+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.