Rails, поиск результатов на основе общей ассоциации с помощью Active Record Query или AREL

Я работаю над проектом rails, в котором у меня есть пользователь, который has_many Teams через модель членства. Пользователь имеет настройку конфиденциальности, которая может быть (общедоступной, частной или защищенной)

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

Я мог бы сделать это как два отдельных запроса, а затем объединить полученные массивы, но я предполагаю, что «лучше» сохранить их как один — я думаю, что он также будет вести себя лучше с will_paginate.

Я думал, что мне может понадобиться использовать Arel из-за условия .or, но я просто не могу понять, какие соединения необходимы для работы с общими командами.

В этом отношении я новичок в AREL, SQL и Stackoverflow, поэтому прошу прощения, если это не имеет особого смысла.


person JeremiahAlex    schedule 10.04.2013    source источник


Ответы (1)


Я предполагаю следующую настройку:

class User < AR
  has_many :memberships
  has_many :teams, through: :memberships
end

class Membership < AR
  belongs_to :user
  belongs_to :team
end

class Team < AR
  has_many :memberships
  has_many :teams, through: :memberships
end

Тогда это должно работать:

sql = <<QUERY
SELECT users.* FROM users WHERE users.privacy_setting = 'public'
UNION
SELECT users.* FROM users JOIN memberships ON users.id = memberships.user_id
WHERE memberships.team_id IN (#{current_user.team_ids})
AND users.privacy_setting = 'protected'
QUERY

# use the paginated find_by_sql method (provided by will_paginate)
User.paginate_by_sql(sql, page: params[:page], per_page: 50)

Конечно, имена столбцов и т. д. зависят от вашей настройки...

PS: Думаю, AREL не нужен...

person Vapire    schedule 10.04.2013
comment
Идеально. Делает именно то, что мне нужно было сделать. Я оставлю играть с AREL еще на один день. Большое тебе спасибо! - person JeremiahAlex; 11.04.2013