在Rails中可能滥用模型的多态关联3

时间:2012-05-31 18:51:00

标签: ruby-on-rails-3 associations polymorphic-associations

在我的应用程序中,我有三个感兴趣的模型。第一个是患者模型,它具有多种记录模型。同样,Record模型具有多种诊断模型。最初我让Patient模型通过以下方式访问诊断:

:has_many :diagnoses, :through => :records

然而我遇到的问题是我还希望Patient模型能够创建独立于Record模型的Diagnosis对象。例如,在入院期间,患者可能被诊断出患有新病症。然而,她可能也有患病史(先前诊断)的历史,所以我想跟踪这一点,而不必诉诸于创建新模型。

我尝试使用here描述的多态关联,这样我的模型看起来像:

class Patient < ActiveRecord::Base
  has_many :records
  has_many :diagnoses, :as => :medical_history
  # ...
end

class Record < ActiveRecord::Base
  belongs_to :patient
  has_many :diagnoses, :as => :medical_history
  # ...
end

class Diagnosis < ActiveRecord::Base
  belongs_to :medical_history, :polymorphic => true
  # ...
end

我遇到的问题是,虽然我可以通过Record对象成功创建Diagnosis对象,但当我调用p.diagnoses(其中p是Patient对象)时,它不会让我访问所有的诊断对象,就像我期望的那样。

重申一下,我想要的是能够通过Record模型或Patient模型创建一个Diagnosis对象,但是能够让Patient模型访问通过自身创建的所有Diagnosis对象或通过记录模型(由于记录模型属于患者模型,因此应该是可能的)。

我很确定这不是我真正理解多态关联的工作方式,我也可能完全滥用多态关联。所以我感谢所有的帮助。谢谢!

1 个答案:

答案 0 :(得分:1)

我认为你对多态的使用是恰当的。

通过记录创建的诊断(在此上下文中的一个令人困惑的术语,因为它可能意味着患者记录或数据库记录)不会自动添加到患者。你需要做两件事之一:

  1. 在Record模型上使用回调(例如,after_save),将所有诊断添加到Record.patient并调用Record.patient.save。请注意,您的患者也可能有回调,所以要小心他们不要互相打电话。

  2. 在患者中添加一种方法,以便在需要时将p.diagnoses与p.records.diagnoses结合起来。如(未经测试的代码):

    def diagnoses_all
      // you could memoize this if so inclined
      (diagnoses + records.collect{|r| r.diagnoses}.flatten).uniq
    end
    
  3. 在任何一种情况下,您都可以随时拨打Patient.records.diagnoses,以便不会丢失知识。但是,在第一种情况下,如果您想知道通过患者创建了哪些诊断,则必须编写另一种方法来基本上反转diagnoses_all,即从Patient.diagnoses中减去Patient.records.diagnoses。

    为了更好地了解正在发生的事情,请查看为3个表生成的(假设SQL)架构。在控制台中,实例化患者,调用p.diagnoses和p.records.diagnoses,查看生成的SQL的日志。