You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rails中为医生与患者关联设置两类患者的数量限制

Rails中按患者类型限制医生关联数量的实现方案

1. 给患者模型添加类型字段

首先需要给patients表新增一个区分患者类型的字段,推荐用枚举(enum)管理,逻辑更清晰:

  • 生成迁移文件:
rails generate migration AddPatientTypeToPatients patient_type:string
rails db:migrate
  • 在Patient模型中定义枚举:
class Patient < ApplicationRecord
  belongs_to :doctor
  enum patient_type: { free: 'free', paid: 'paid' }
end

2. 在医生模型中添加数量限制验证

在Doctor模型里自定义验证方法,分别统计免费、付费患者的数量,和预设限制值对比:

class Doctor < ApplicationRecord
  has_many :patients

  # 把限制值设为常量,方便后续修改
  MAX_FREE_PATIENTS = 10
  MAX_PAID_PATIENTS = 50

  validate :check_free_patient_limit, :check_paid_patient_limit

  private

  def check_free_patient_limit
    free_patient_count = patients.free.count
    if free_patient_count >= MAX_FREE_PATIENTS
      errors.add(:base, "免费患者数量已达上限(#{MAX_FREE_PATIENTS}人)")
    end
  end

  def check_paid_patient_limit
    paid_patient_count = patients.paid.count
    if paid_patient_count >= MAX_PAID_PATIENTS
      errors.add(:base, "付费患者数量已达上限(#{MAX_PAID_PATIENTS}人)")
    end
  end
end

3. 可选:添加关联回调(避免批量添加绕过验证)

如果存在批量添加患者的场景,上面的验证可能失效,这时可以用before_add回调在添加单个患者前做检查:

class Doctor < ApplicationRecord
  has_many :patients, before_add: :check_patient_limit_before_add

  MAX_FREE_PATIENTS = 10
  MAX_PAID_PATIENTS = 50

  # 保留原有验证方法,处理手动保存的场景
  validate :check_free_patient_limit, :check_paid_patient_limit

  private

  def check_patient_limit_before_add(patient)
    case patient.patient_type
    when 'free'
      if patients.free.count >= MAX_FREE_PATIENTS
        raise ActiveRecord::Rollback, "免费患者数量已达上限"
      end
    when 'paid'
      if patients.paid.count >= MAX_PAID_PATIENTS
        raise ActiveRecord::Rollback, "付费患者数量已达上限"
      end
    end
  end

  # 以下是原有验证方法
  def check_free_patient_limit
    free_patient_count = patients.free.count
    if free_patient_count >= MAX_FREE_PATIENTS
      errors.add(:base, "免费患者数量已达上限(#{MAX_FREE_PATIENTS}人)")
    end
  end

  def check_paid_patient_limit
    paid_patient_count = patients.paid.count
    if paid_patient_count >= MAX_PAID_PATIENTS
      errors.add(:base, "付费患者数量已达上限(#{MAX_PAID_PATIENTS}人)")
    end
  end
end

补充说明

  • 如果需要给不同医生设置不同的限制值(比如不同等级的医生配额不同),可以给doctors表新增max_free_patients和max_paid_patients字段,把验证里的常量换成实例属性即可。
  • 验证提示文案可以根据业务需求调整成更贴合场景的表述。

内容的提问来源于stack exchange,提问作者Andrew Kancev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 15:35:28