Rails ActiveRecord: как выбрать всех пользователей с заданным разрешением?

У меня есть модель под названием «Пользователи», некоторые из которых считаются авторами. Это достигается с помощью таблицы «Роли», в которой перечислены различные роли: «Автор» — одна из них. Связь «многие ко многим» в таблице «Разрешения» связывает роли и пользователей.

Чтобы проверить, есть ли у пользователя разрешение автора, у меня есть метод, который проходит через разрешения, связанные с этим конкретным пользователем, и возвращает, ссылается ли какое-либо из них также на разрешение автора.

Эта система сослужила мне хорошую службу. Однако это затрудняет поиск и заказ авторов на сайте. Я бы хотел сделать что-то простое и изящное, в идеале вроде именованной области, которая позволит мне говорить такие вещи, как Users.authors.order("date_joined") или что-то в этом роде.

Как и сейчас, у меня нет другого способа получить группу пользователей «Автор», кроме как вытащить всех пользователей из базы данных, просматривая их по одному, ища их разрешение автора, а затем добавляя их в массив пользователей, если он найден.

Это кажется довольно некрасивым, тем более, что мне приходится делать это каждый раз, когда я хочу представить список авторов в представлении.

Есть ли способ лучше?

ИЗМЕНИТЬ — Решение:

Следуя приведенным ниже полезным советам и советам с http://railscasts.com/episodes/215-advanced-queries-in-rails-3?view=asciicast Мне удалось собрать следующее.

В User.rb:

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

В 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"))

И вуаля! Теперь я могу позвонить Users.authors, и это работает как шарм.


person isthmus    schedule 13.05.2012    source источник


Ответы (2)


Сохраните структуру схемы, которая у вас есть, но не забудьте добавить правильные индексы таблиц.

Затем, чтобы запросить пользователей в определенных ролях, вы можете сделать

User.all(:joins => :roles,
         :conditions => {:roles => {:id => pick_a_role_id}})
person Dty    schedule 14.05.2012
comment
Это как раз то, на что я надеялся. Огромное спасибо. (Я также получил хорошую помощь по синтаксису от railscasts.com /эпизоды/) - person isthmus; 14.05.2012

вы смотрели на CanCan? Вероятно, потребуется небольшой рефакторинг, в основном для создания метода current_user. Руководство по ролям можно найти здесь

person Benjamin Udink ten Cate    schedule 13.05.2012
comment
Хорошее предложение. Райан Бейтс — мой личный герой Rails, так что я очень доволен CanCan... как только у меня появится время на рефакторинг. Спасибо за внимание. - person isthmus; 14.05.2012
comment
@isthmus, хотя CanCan великолепен, он не связан с ролями. Так что вам все равно нужно сделать эту часть самостоятельно. Или используйте драгоценный камень и т. д. По сути, использование CanCan не решит проблему, которую вы здесь публикуете. - person Dty; 14.05.2012