Question

I have an api. In that api is a basecontroller that all other controllers inherit from. The basecontroller handles authentication and whether or not the API is on at all, etc.

There are users, and users can belong to a group. Users table has a group_id column.

I'm trying to introduce a new feature, whereby a select on the settings page for admin controls which users are shown from what groups. If an option is selected, only users from that group should be shown by the api.

I could go into each controller (there is one controller for each of a few different tasks - getting all users info, just active_users ids, a single users information, etc) and add the extra statement to each

if !settings.api_group.nil?
  #add the additional where("group_id = ?, settings.group_id)

but that seems like a lot of repeating myself (doing it in 8 different places)

Is there some way to add something to the basecontroller that says:

if this setting option is not nil, only return user information if they are in this group

?

Thanks

Was it helpful?

Solution

You can add a method to the BaseController, and call it in each action that should have this restriction. Something like this:

in base_controller.rb:

protected

def filtered_users
  if settings.api_group
    User.where(:group_id => settings.group_id)
  else
    User.scoped
  end
end

and in the controllers that inherit from it:

def index
  @users = filtered_users
end

This way, you only define the filtering in one place. If it needs to change later, you only have to change it in one place. Because filtered_users actually returns a Relation, you can continue to alter the query by tacking additional .where clauses, etc, like this:

@users = filtered_users.joins(:posts).where('posts.created_at > ?', 1.week.ago)

OTHER TIPS

FYI my answer was exactly what I thought it might have to be in the initial post. I'd love for there to be a more DRY solution, but I ended up doing something like this:

IN USER MODEL

def find_in_api_group
  # NOTE settings.api_group is a string => "1,2,4"
  if settings.api_group.nil? || settings.api_group.blank?
    where("") # THERE HAS TO BE BETTER WAY OF SAYING THIS WITHOUT INTERRUPTING THE CHAIN
  else
    where("group_id IN (?)", settings.api_group)
  end
end

IN VARIOUS CONTROLLERS

user = User.find_in_api_group 
#then chain various error tests and additional activeRecord statement
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top