2013-08-28 2 views
1

В моей БД У меня есть отношение «многие ко многим» (HABTM) между Пользователями и Ролями. Я пытаюсь получить все имена ролей для пользователей, связанных с конкретным секретарем.Преобразование инструкции отображения Ruby в запрос ActiveRecord?

мне удалось булыжник следующие вместе:

class Secretary < ActiveRecord::Base 
    def getRoles 
    rolenames = Set.new 
    Role.all.map { |role| role.users.map { |user| rolenames << role.name if user.manager.secretary == self } } 
    rolenames.to_a 
    end 
end 

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

Возможно ли преобразовать вышеуказанное в более «родной» запрос ActiveRecord?

ответ

1

Вы не указали достаточно информации, чтобы получить четкое изображение вашей модели. Из того, что ты предоставить я предполагаю, это выглядит с точки зрения секретаря:

Secretary 
has_many :managers 

Manager 
has_namy :users 

User 
has_many :roles 

При получении записей из глубоко вложенных моделей полезно думать в терминах идентификаторов (внешние ключи): Rails Nested SQL Queries

Поскольку Rails автоматически преобразует записи в идентификаторами для вас внутри хэш-версии, где оператор ..

Role.where(:user_id => User.where(:manager_id => managers)) 

должен получить ответ, если мои предположения о вашей модели являются правильными.

EDIT: ОК, HABTM немного загрязняет воду. Мы не можем делать вложенные файлы, но мы все еще можем делать то же самое, что и с некоторым отображением, не слишком сильно ударяя по базе данных. Попробуйте следующее:

User.includes(:roles).where(manager_id: managers).flat_map(&:roles).map(&:name) 
+0

Как упоминалось в вопросе, отношения между пользователями и ролями являются отношением HABTM (has_and_belongs_to_many, с таблицей соединений). У менеджеров много пользователей системы, и у секретарей есть много менеджеров. Таким образом, запрос должен возвращать набор ролей для всех пользователей под определенным менеджером под определенным секретарем. Означает ли это вопрос? – user456584

+0

Это должно работать тогда. Ты это пробовал? – seph

+0

Внутренний запрос работает, но внешний запрос 'Role.where (: user_id => ...) не возвращает ничего. Я также попробовал 'Role.include (: users) .where (: user_id => ...)' с похожими результатами. – user456584

0

кажется, что ваши модели, как это:

Role 
    has_many :users 
User 
    belongs_to :role 
    has_one :manager, :class => 'User' 

В случае, просто внутреннее присоединение к таблицам должны вернуть результаты вы после:

SELECT roles.* FROM roles 
INNER JOIN users u ON u.role_id = roles.id 
INNER JOIN users m ON m.id = u.id 

Этот запрос может быть переведен что-то вроде этого:

Role.joins(:users => :manager) 
+0

В этом случае ни менеджеры, ни секретари не являются пользователями. – user456584

Смежные вопросы