concord-consortium/rigse

View on GitHub
rails/app/policies/portal/teacher_policy.rb

Summary

Maintainability
A
25 mins
Test Coverage
class Portal::TeacherPolicy < ApplicationPolicy

  def self.teacher_query(user)
    return "
      SELECT portal_teachers.id FROM portal_teachers
      INNER JOIN
        admin_cohort_items __aci_scope ON (__aci_scope.item_id = portal_teachers.id)
      INNER JOIN
          admin_cohorts __ac_scope ON (__ac_scope.id = __aci_scope.admin_cohort_id)
      INNER JOIN
          admin_project_users __apu_scope ON (__apu_scope.project_id = __ac_scope.project_id)
      WHERE
          __aci_scope.item_type = 'Portal::Teacher'
      AND
          __apu_scope.user_id = #{user.id}
      AND
          (__apu_scope.is_admin = 1 OR (__apu_scope.is_researcher = 1 AND (__apu_scope.expiration_date IS NULL OR expiration_date > '#{Date.today.to_s(:db)}')))
      UNION
        SELECT id
        FROM portal_teachers
        WHERE user_id = #{user.id}
    "
  end

  class Scope < Scope
    def resolve
      if user && user.has_role?('admin')
        all
      elsif user && (user.is_project_admin? || user.is_project_researcher?)
        # prevents a bunch of unnecessary model loads by not using the model scopes
        # Also covers some tricky edge cases.
        # See this bug: https://www.pivotaltracker.com/story/show/169465198
        sql = Portal::TeacherPolicy::teacher_query(user)
        ids = Portal::Teacher.connection.select_values(sql)
        # Return a new scope selecting those records:
        scope
          .where('portal_teachers.id IN (?)', ids)
          .distinct

      elsif (user.portal_teacher)
        scope.where('user_id = (?)', user.id)
      end
    end
  end

  def can_view_teacher?
    return false if user.nil?
    return true if owner? || admin?

    if user.is_project_admin? || user.is_project_researcher?
      sql = Portal::TeacherPolicy.teacher_query(user)
      teacher_ids = Portal::Teacher.connection.select_values(sql)
      return teacher_ids.include?(record.id.to_s)
    end

    false
  end

  def show?
    can_view_teacher?
  end

  def get_teacher_project_views?
    can_view_teacher?
  end

end