Frage

I've got a model called Users, some of whom are considered Authors. This is accomplished through a table called Roles, which lists a number of different roles: "Author" is one. A many-to-many association in a table called Permissions links Roles and Users.

To check whether a User has the Author permission, I have a method that runs through the Permissions linked to that particular User and returns whether any of them also links to the Author permission.

This system has served me well. However, it makes it clunky to search and order the Authors on the site. What I'd like to do is something simple and graceful, ideally like a named scope that will allow me to say things like Users.authors.order("date_joined") or something like that.

As it is right now, I don't have any way to get the group of "Author" users other than pulling all Users out of the database, running through them one at a time, searching for their Author permission, and then adding them to an array of Users if it is found.

This seems rather ungraceful, especially as I have to do it every time I want to present the list of Authors in a view.

Is there a better way?

EDIT -- Solution:

Following the helpful advice below and the tips from http://railscasts.com/episodes/215-advanced-queries-in-rails-3?view=asciicast I was able to put together the following.

In User.rb:

    class User < ActiveRecord::Base
      scope :authors, joins(:permissions) & Permission.author_permissions
      scope :admins, joins(:permissions) & Permission.admin_permissions

In Permission.rb:

    class Permission < ActiveRecord::Base
      scope :author_permissions, where("role_id = ?", Role.find_by_rolename("author"))
      scope :admin_permissions, where("role_id = ?", Role.find_by_rolename("administrator"))

And voila! Now I can call Users.authors and it works like a charm.

War es hilfreich?

Lösung

Keep the schema structure that you have but make sure to add the proper table indexes.

Then to query for users in specific roles you can do

User.all(:joins => :roles,
         :conditions => {:roles => {:id => pick_a_role_id}})

Andere Tipps

have you looked at CanCan? It will probably require a little refactoring, mostly to create a current_user method. A guide to roles can be found here

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top