app/queries/user_query.rb
class UserQuery
def self.relations(model:, actor:)
rels = []
if model.is_a?(Group) and model.members.exists?(actor.id)
rels.push User.joins('LEFT OUTER JOIN memberships m ON m.user_id = users.id').
where('m.group_id IN (:group_ids) AND m.revoked_at IS NULL', {group_ids: model.group.id})
end
if model.nil? or actor.can?(:add_guests, model)
group_ids = if model && model.group.present? && (!model.is_a?(Group) || model.parent_id)
actor.group_ids & model.group.parent_or_self.id_and_subgroup_ids
else
actor.group_ids
end
rels.push User.joins('LEFT OUTER JOIN memberships m ON m.user_id = users.id').
where('m.group_id IN (:group_ids) AND m.revoked_at IS NULL', {group_ids: group_ids})
# people who have been invited by actor
rels.push(
User.joins("LEFT OUTER JOIN discussion_readers dr on dr.user_id = users.id").
where("dr.inviter_id = ? AND revoked_at IS NULL AND guest = TRUE", actor.id)
)
rels.push(
User.joins("LEFT OUTER JOIN stances on stances.participant_id = users.id").
where("stances.inviter_id = ? AND revoked_at IS NULL AND guest = TRUE", actor.id)
)
end
if model.present? && (actor.can?(:add_members, model) || actor.can?(:add_voters, model))
if model.group.present?
rels.push User.joins('LEFT OUTER JOIN memberships m ON m.user_id = users.id').
where('m.group_id IN (:group_ids) AND m.revoked_at IS NULL', {group_ids: model.group.id})
end
if model.discussion_id
rels.push(
User.joins('LEFT OUTER JOIN discussion_readers dr ON dr.user_id = users.id').
where('dr.discussion_id': model.discussion_id).where('dr.revoked_at IS NULL and dr.guest = TRUE')
)
rels.push(
User.joins('LEFT OUTER JOIN stances ON stances.participant_id = users.id').
where('stances.poll_id': model.discussion.poll_ids).where("stances.revoked_at IS NULL and stances.guest = TRUE")
)
end
if model.poll_id
rels.push(
User.joins('LEFT OUTER JOIN stances ON stances.participant_id = users.id').
where('stances.poll_id': model.poll_id).where("stances.revoked_at IS NULL AND stances.guest = TRUE")
)
end
end
rels
end
def self.invitable_user_ids(model: , actor:, user_ids: )
relations(model: model, actor: actor).map do |rel|
rel.where(id: user_ids).pluck(:id)
end.flatten.uniq.compact
end
def self.invitable_search(model:, actor:, q: nil, limit: 50)
ids = relations(model: model, actor: actor).map do |rel|
rel.active.verified.search_for(q).limit(limit).pluck(:id)
end.flatten.uniq.compact
User.where(id: ids).order(:memberships_count).limit(50)
end
end