使用权威策略来限制另一个类

时间:2017-10-10 18:59:26

标签: ruby-on-rails pundit

我有一个名为dispatch的模型,是一个连接表,它涉及另外两个模型,推荐请求和临床医生。在我的应用程序中,员工用户将创建一个推荐请求记录,其中包含有关患者所需内容的一些详细信息。一些未构建的逻辑将找到匹配患者记录中所述的至少一个保险的所有临床医生用户,并且这将导致向这些临床医生中的每一个发送邮件。调度模型是我试图记录推荐请求和临床医生之间的关系,所以我知道哪些临床医生收到了电子邮件,所以我可以记录他们的回答(是或否)。

临床医生也属于市场,员工属于属于市场的大学。

每位临床医生都有临床医师资料,除了clincian_profiles表之外,还有一个clinician_profiles_insurances表,所以我可以给作为临床医生的给定用户打电话给.clinician_profile.insurances并返还他们所有的保险。

在给定的推荐请求中,我也可以致电.insurances以显示患者的所有保险。

我正在尝试在dispatch new方法中使用Pundit策略范围来执行以下操作:

- 仅显示与员工用户大学位于同一市场的临床医生用户。

- 仅显示与转诊请求至少有一个匹配保险的临床医生用户。

到目前为止,这是我最好的刷卡,它甚至不能限制市场的范围。我做错了什么?

发货政策

    class DispatchPolicy < ApplicationPolicy
  class Scope
    attr_reader :user, :scope

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

    def resolve

      if user.admin?
        scope.all
      else
        scope.joins(:clinician).merge(User.where(market: user.market))
      end
    end
  end

我的用户有多个角色:

enum role: { staff: 0, clinician: 1, admin: 2 }

以下是关系:

class Dispatch < ApplicationRecord
    belongs_to :referral_request
    belongs_to :clinician, class_name: 'User', foreign_key: 'user_id'

class ReferralRequest < ApplicationRecord
  belongs_to :user, -> { where role: :staff }
  has_many :dispatches
  has_many :clinicians, through: :dispatches

module StaffUser
  extend ActiveSupport::Concern

  included do
    belongs_to :university
    has_many :patients
    has_many :referral_requests
    validates :university_id, presence: true, if: :staff?
  end

这是我在Dispatches控制器中的新方法:

def new
@clinicians = policy_scope(Dispatch)
@dispatch = @referral_request.dispatches.new
end

以下是dispatches / new.html.erb中的表格,我试图向所有用户显示

1)是临床医生 2)与员工用户大学属于同一市场 3)在临床医师档案中至少有一项保险与保险申请相关的保险相匹配。

<% @clinicians.each do |clinician| %>
  <tr>
    <td><%= clinican.id %></td>
    <td><%= clinican.name %></td>
    <td><%= clinican.market.name %></td>
    <td><%= clinican.clinician_profile.insurances.map(&:name).to_sentence %></td>
    <td><%= clinican.clinician_profile.genders.map(&:name).to_sentence %></td>
    <td><%= clinican.clinician_profile.races.map(&:name).to_sentence %></td>
    <td><%= clinican.clinician_profile.languages.map(&:name).to_sentence %></td>
  </tr>
<% end %>
</tbody>
</table>

保险模式:

class Insurance < ApplicationRecord
    has_and_belongs_to_many :patients
    has_and_belongs_to_many :clinician_profiles
    has_and_belongs_to_many :markets
end

患者模型

class Patient < ApplicationRecord
  belongs_to :author, -> { where role: :staff }, class_name: 'User', foreign_key: 'user_id'

  has_and_belongs_to_many :genders
  has_and_belongs_to_many :concerns
  has_and_belongs_to_many :insurances
  has_and_belongs_to_many :races
  has_many :referral_requests
  belongs_to :staff_doctor, class_name: 'User', foreign_key: 'staff_doctor_id'

  def has_referral?
    !self.referral_requests.empty?
  end
end

**Clinician concern**
require 'active_support/concern'

module ClinicianUser
  extend ActiveSupport::Concern

  included do
    has_one :clinician_profile
    has_many :lists
    has_many :universities, through: :lists
    has_many :dispatches
    has_many :referral_requests, through: :dispatches
    after_create :create_clinician_profile
    belongs_to :market
    validates :market_id, presence: true, if: :clinician?
  end

  class_methods do
  end
end

员工关注

require 'active_support/concern'

module StaffUser
  extend ActiveSupport::Concern

  included do
    belongs_to :university
    has_many :patients
    has_many :referral_requests
    validates :university_id, presence: true, if: :staff?
  end

  class_methods do
  end
end

临床医师档案模型

class ClinicianProfile < ApplicationRecord
  belongs_to :user, -> { where role: :clinician }
  has_and_belongs_to_many :languages
  has_and_belongs_to_many :races
  has_and_belongs_to_many :insurances
  has_and_belongs_to_many :genders
end

我是否以正确的方式思考这个问题?对于我正在尝试做的全部或部分内容,专家政策是一个很好的解决方案吗?感谢所有反馈。我显然有点失落。

1 个答案:

答案 0 :(得分:0)

为什么不一次解决一个问题?

暂时忽略Pundit并提出一个返回您期望的ActiveRecord查询。

user = User.where(role: :staff).first
Dispatch.joins(:clinician).merge(User.where(market: user.market))

这加入了“临床医生”..由于模型中的“class:User”,我认为其实际上是“用户”表。 对于第1部分和第2部分,此查询似乎很好。

运行该AR查询,应首先加入与用户的所有调度,并仅选择与传递到策略中的“当前用户”具有相同“市场”的调度。

但请记住:

@clinicians = policy_scope(Dispatch)

正在返回调度,而不是“临床医生”(用户),所以在您编写的代码中,“clinicalians.id”将是您不想要的调度表ID?除非我弄错了。

尝试让第1部分和第2部分首先工作,如果它还没有工作的话。

第3部分“在其临床医师档案中至少有一项与推荐请求相关的保险相匹配的保险。”

听起来你还要加入“推荐请求”,并做更多的SQL,我只是不知道保险是如何计算在你的 域名(是has_many:insurance_plans等,需要更多信息)