在 Rails Ruby 中的自我引用关联
Self referential association in Ruby on Rails
我有一个应用程序,其中包含“患者”资源。我想在患者之间建立一个与病毒感染相关的自我联想。因此,患者可以是感染者、被感染者或两者兼而有之。当我创建一个病人时,我想 select 哪个(另一个)病人感染了他。所以我在“患者”中添加了一个“patient_id”字段。我的代码如下:
患者模型:
class Patient < ApplicationRecord
has_many :infected, class_name: 'Patient', foreign_key: :patient_id
belongs_to :infectant, optional: true, class_name: 'Patient'
end
患者表格:
<div class="field">
<%= form.label :patient_id %>
<%= form.collection_select(:patient_id, Patient.all, :id, :document_number) %>
</div>
<div class="field">
<%= form.label :first_name %>
<%= form.text_field :first_name %>
</div>
<div class="field">
<%= form.label :last_name %>
<%= form.text_field :last_name %>
</div>
<div class="field">
<%= form.label :document_number %>
<%= form.number_field :document_number %>
</div>
<div class="field">
<%= form.label :birth_date %>
<%= form.datetime_select :birth_date %>
</div>
<div class="field">
<%= form.label :province %>
<%= form.number_field :province %>
</div>
<div class="field">
<%= form.label :city %>
<%= form.text_field :city %>
</div>
<div class="field">
<%= form.label :status %>
<%= form.number_field :status %>
</div>
患者指数:
<table>
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
<th>Document number</th>
<th>Birth date</th>
<th>Province</th>
<th>City</th>
<th>Status</th>
<th>Infectant</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @patients.each do |patient| %>
<tr>
<td><%= patient.first_name %></td>
<td><%= patient.last_name %></td>
<td><%= patient.document_number %></td>
<td><%= patient.birth_date %></td>
<td><%= patient.province %></td>
<td><%= patient.city %></td>
<td><%= patient.status %></td>
<td><%= patient.patient_id %></td>
<td><%= link_to 'Show', patient %></td>
<td><%= link_to 'Edit', edit_patient_path(patient) %></td>
<td><%= link_to 'Destroy', patient, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
有了这个索引,我可以显示感染者的身份。
我想要的是在索引中显示感染者的“document_number”。但是如果我写的不是“patient.patient_id”,而是“patient.infectant.document_number”,但是因为“患者”没有“感染”字段,所以它 return 错误。
解决这个问题的一种方法是使用 delegate
:
class Patient < ApplicationRecord
# ...
delegate :document_number,
to: :infectant,
prefix: true,
allow_nil: true
end
这会让你调用:
<td><%= patient.infectant_document_number || "default value" %></td>
不冒零错误的风险。
我有一个应用程序,其中包含“患者”资源。我想在患者之间建立一个与病毒感染相关的自我联想。因此,患者可以是感染者、被感染者或两者兼而有之。当我创建一个病人时,我想 select 哪个(另一个)病人感染了他。所以我在“患者”中添加了一个“patient_id”字段。我的代码如下:
患者模型:
class Patient < ApplicationRecord
has_many :infected, class_name: 'Patient', foreign_key: :patient_id
belongs_to :infectant, optional: true, class_name: 'Patient'
end
患者表格:
<div class="field">
<%= form.label :patient_id %>
<%= form.collection_select(:patient_id, Patient.all, :id, :document_number) %>
</div>
<div class="field">
<%= form.label :first_name %>
<%= form.text_field :first_name %>
</div>
<div class="field">
<%= form.label :last_name %>
<%= form.text_field :last_name %>
</div>
<div class="field">
<%= form.label :document_number %>
<%= form.number_field :document_number %>
</div>
<div class="field">
<%= form.label :birth_date %>
<%= form.datetime_select :birth_date %>
</div>
<div class="field">
<%= form.label :province %>
<%= form.number_field :province %>
</div>
<div class="field">
<%= form.label :city %>
<%= form.text_field :city %>
</div>
<div class="field">
<%= form.label :status %>
<%= form.number_field :status %>
</div>
患者指数:
<table>
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
<th>Document number</th>
<th>Birth date</th>
<th>Province</th>
<th>City</th>
<th>Status</th>
<th>Infectant</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @patients.each do |patient| %>
<tr>
<td><%= patient.first_name %></td>
<td><%= patient.last_name %></td>
<td><%= patient.document_number %></td>
<td><%= patient.birth_date %></td>
<td><%= patient.province %></td>
<td><%= patient.city %></td>
<td><%= patient.status %></td>
<td><%= patient.patient_id %></td>
<td><%= link_to 'Show', patient %></td>
<td><%= link_to 'Edit', edit_patient_path(patient) %></td>
<td><%= link_to 'Destroy', patient, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
有了这个索引,我可以显示感染者的身份。 我想要的是在索引中显示感染者的“document_number”。但是如果我写的不是“patient.patient_id”,而是“patient.infectant.document_number”,但是因为“患者”没有“感染”字段,所以它 return 错误。
解决这个问题的一种方法是使用 delegate
:
class Patient < ApplicationRecord
# ...
delegate :document_number,
to: :infectant,
prefix: true,
allow_nil: true
end
这会让你调用:
<td><%= patient.infectant_document_number || "default value" %></td>
不冒零错误的风险。