Ruby on Rails中统计患者用血次数并关联患者表展示问题
解决Rails患者用血次数统计与关联展示问题
首先把模型关联理清楚,这是实现功能的基础:
- 患者表(Patient)和血液制品输注表(BloodProductTransfusion)是一对多关系,一个患者对应多次输注
- 患者表和并发症记录表(Complication)也是一对多关系,一个患者可能有多个并发症
第一步:修正模型关联
在app/models/patient.rb里添加关联,因为你的主键是UPI,需要手动指定外键:
class Patient < ApplicationRecord self.primary_key = 'upi' # 明确主键为UPI has_many :blood_product_transfusions, foreign_key: 'upi', dependent: :destroy has_many :complications, foreign_key: 'upi', dependent: :destroy # 实例方法:获取当前患者的用血次数 def blood_transfusion_count blood_product_transfusions.count end # 实例方法:判断当前患者是否有并发症 def has_complication? complications.exists? end end
第二步:控制器查询优化
如果患者数据量小,直接用Patient.all即可,但数据量大时会出现N+1查询问题(循环每个患者时单独查数据库)。推荐用一次性查询把统计结果直接带出来,在app/controllers/patients_controller.rb的index方法中编写:
def index @patients = Patient.left_joins(:blood_product_transfusions) .select( 'patients.*', 'COUNT(blood_product_transfusions.id) AS blood_transfusion_count', 'CASE WHEN EXISTS(SELECT 1 FROM complications WHERE complications.upi = patients.upi) THEN TRUE ELSE FALSE END AS has_complication' ) .group('patients.upi') end
这种方式会把用血次数、并发症状态和患者基础数据一次性查出来,避免重复查询数据库,效率更高。
第三步:页面展示
在视图文件(比如app/views/patients/index.html.erb)中直接调用属性或方法展示数据:
<table> <thead> <tr> <th>UPI</th> <th>诊断</th> <th>用血次数</th> <th>是否有并发症</th> </tr> </thead> <tbody> <% @patients.each do |patient| %> <tr> <td><%= patient.upi %></td> <td><%= patient.diagnosis %></td> <td><%= patient.blood_transfusion_count %></td> <td><%= patient.has_complication? ? '是' : '否' %></td> </tr> <% end %> </tbody> </table>
关于你之前的.group.count问题
你用BloodProductTransfusion.group(:upi).count得到的是{upi: 次数}格式的哈希,要和Patient对象关联的话,需要循环每个患者去哈希中匹配对应值,不仅麻烦还容易出错。直接把统计逻辑整合到Patient的查询或模型方法里,更符合Rails开发习惯,完全不需要额外编写BloodProductCount类。
内容的提问来源于stack exchange,提问作者Dän Punkt
相关产品推荐
相关产品推荐

