Rails应用程序的方法

时间:2009-07-18 13:28:00

标签: ruby-on-rails

我正在进行从传统数据库驱动的Windows应用程序到Rails应用程序的相当大的转换。由于涉及大量的表单和数据库表,我想确保在得到太多之前我已经有了正确的方法。

我主要担心的是尽量减少我必须编写的代码量。有许多模型可以相互作用,我想确保我正确使用它们。这是一组简化的模型:

类患者<的ActiveRecord :: Base的   has_many:PatientAddresses   has_many:PatientFileStatuses 端

类PatientAddress<的ActiveRecord :: Base的   belongs_to:病人 端

class PatientFileStatus<的ActiveRecord :: Base的   belongs_to:病人 端

控制器确定是否选择了患者;其他一切都是基于此。

在视图中,我将需要来自每个模型的数据。但似乎我必须在我的控制器中为我想要使用的每个属性编写一个实例变量。所以我开始编写这样的代码:

@patient = Patient.find(session [:patient]) @patient_addresses = @ patient.PatientAddresses @patient_file_statuses = @ patient.PatientFileStatuses

@enrollment_received_when = @patient_file_statuses [0] .EnrollmentReceivedWhen @consent_received = @patient_file_statuses [0] .ConsentReceived @consent_received_when = @patient_file_statuses [0] .ConsentReceivedWhen

前三行抓住了Patient模型及其关系。接下来的三行是我从其中一个关系中为视图提供值的示例。

视图包含文本字段和选择字段的组合,用于显示上述数据。例如:

“val1”,“val2”=>“val2”,“Written”=>“Written”} ,: include_blank => true)%> :force%>

(顺便说一句,选择标签并没有真正起作用;我想我必须使用collection_select?)

我的问题是:

  1. 我是否必须在控制器中手动声明每个实例变量的值,或者我可以/应该在视图中执行它吗?
  2. 为不是主要模型的数据显示选择标记的正确方法是什么?
  3. 当我将更改保存到此表单时,是否必须手动选择每个模型的属性并单独保存?或者有没有办法命名字段,以便ActiveRecord做正确的事情?
  4. 提前致谢, 亚伦。

2 个答案:

答案 0 :(得分:2)

  

我是否必须在控制器中手动声明每个实例变量的值,或者我可以/应该在视图中执行它吗?

作为一般经验法则,您应该避免在视图中定义实例变量;特别是如果它调用模型。维护起来可能会让人感到困惑,更难以测试,也无法重复使用。

  

为不是主要模型的数据显示选择标记的正确技巧是什么?

如果“辅助”模型与“主要”模型相关联,则可以将方法链接在一起。在模型中定义关联时,您将获得these methods for free

# Where attr is an attr belonging to the patient_address which is 
# associated with the patient
<%= @patient.patient_address.attr %>
  

当我去保存对此的更改时   表格,我必须手动挑选出来   每个模型的属性并保存   他们个别?还是有办法   命名这样的字段   ActiveRecord做对了吗?

您将对单个表单中嵌套关联模型的fields_for方法感兴趣。 Railscasts还有一些很好的例子,可以在表格中使用相关模型。

答案 1 :(得分:0)

1)  没有什么可以阻止您在视图中编写任意Ruby代码,因此您只需编写@patient.PatientAddresses,而不是在控制器中定义@patient_addresses。无论如何,这只是锅炉板,如果您希望稍后更改它,很容易通过搜索/替换进行重构。 OTOH我会把这条线

@patient = Patient.find(session[:patient])

在控制器中,因为您只想执行一次查找,查询也可能会发生变化。

3)  save中的ActiveRecord方法有点微妙。通常,它将仅保存调用方法的对象以及任何依赖项。如果该行与另一个表具有外键关系,则可能无法仅保存一行。这意味着代码

patient = Patient.new; file_status.patient = patient

调用patient时会自动保存

file_status.save,因为必须为外键关系生成id patient。然而,拨打patient.save

如果您希望将关联对象与file_status一起保存,则可以在定义Patient关系时指定:autosave => true

详细信息位于the docs