Область применения Rails со сложным оператором SQL, включая OR

Я сейчас работаю над небольшим Rails-проектом. Я использую Pundit для авторизации действий контроллера и прочего. Работа сейчас состоит в том, чтобы использовать Pundit для действия индекса и использовать Pundit's policy_scope в моем контроллере, чтобы получить проекты, которые пользователь может видеть.

Есть 3 способа, которыми пользователь должен иметь возможность видеть проект: - Он - владелец - Он был приглашен - Проект является публичным

Я попробовал несколько решений прямо сейчас, но в итоге сделал следующее:

scope :public_or_involved, -> (user) { 
  joins('LEFT JOIN invitations ON invitations.project_id = projects.id').
  where('projects.is_public = TRUE OR projects.owner_id = ? OR invitations.reciever_id = ?', user.id, user.id) 
}

Это единственный способ получить что-то вроде public_or_involved для работы со следующей областью pundit в project_policy.rb:

class Scope
  attr_reader :user, :scope

  def initialize(user, scope)
    @user = user
    @scope = scope
  end

  def resolve
    scope.public_or_involved(user)
  end
end

Итак, мой вопрос, наконец:

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

2 ответа

Предостережение, я не знаю pundit (я предпочитаю более простой подход DSL в acl9), так что я действительно только конвертирую ваш запрос для вас, вы обычно можете заставить Rails дать вам LEFT JOIN с includes(), и вы можете использовать этот маленький трюк, чтобы получить аккуратнее OR:

scope :public_or_involved,
  -> (user) { includes(:invitations).where(
    where( is_public: true, owner_id: user.id, invitations: { receiver_id: user.id } ).where_values.reduce(&:or)
  )}

По моему опыту, решение, которое у вас есть сейчас, является лучшим. Вы можете использовать что-то вроде Arel, Squeel или MetaWhere, чтобы Ruby-фу ваши строки SQL, но они приходят с дополнительной сложностью.

Если это соответствует вашим требованиям, я бы не стал слишком беспокоиться о том, чтобы сделать его "более Rails-y".

Другие вопросы по тегам