我有一个非常复杂的模型,其中包含许多字段、has_many
关联、由image_column
等添加的图像......
新对象将通过多页表单添加(8 个步骤) - 我应该如何完成这些步骤之间的验证和传播?
我认为validation_group
对于定义每个步骤的验证可能很有用,那么整体设计呢?
我有一个非常复杂的模型,其中包含许多字段、has_many
关联、由image_column
等添加的图像......
新对象将通过多页表单添加(8 个步骤) - 我应该如何完成这些步骤之间的验证和传播?
我认为validation_group
对于定义每个步骤的验证可能很有用,那么整体设计呢?
对于整体设计,您可能希望研究 Presenter 层的概念(Jay Fields 在他的博客条目Rails: Presenter Pattern中定义它)作为一种在处理复杂/多个模型时保持控制器精简和视图愚蠢的方法。
您可以有一系列方法,例如step_1
, step_2
,并且每个方法都检查是否已提交上一步的必要数据。您可以将数据存储在会话中,例如,步骤 3 仍然可以访问在步骤 1 中收集和解析的所有数据。在最后一步中,将您存储在会话中的所有数据加上数据从倒数第二步开始使用,并在数据库中创建一个新行或您正在收集数据的任何内容。如果用户搞砸了一个步骤,将他们重定向到上一步,并使用他们填写的数据为他们填写表格;例如,如果用户搞砸了第 2 步并提交了导致第 3 步的表单,则在您的step_3
方法中发现问题,将用户重定向到step_2
方法,并确保步骤 2 中的表单元素已预先填写。
如果您不想在会话中存储数据,您可以在用户提交第 1 步后创建一个新的数据库行,并在每个后续步骤中收集新数据时更新该行中的字段。您可以在行上有一些“完成”标志,最初将其设置为 0,然后在用户成功完成所有步骤后将其设置为 1。
您还可以允许用户转到前面的步骤(例如,让用户在第 5 步时返回第 3 步)。
假设您的第一步有一个包含“名称”和“电子邮件”字段的表单。在您的step_2
方法中,您应该验证params[:name]
并且params[:email]
已通过并且有效。将它们存储在会话或数据库行中,无论您选择什么。然后在第 2 步中,您有一个包含“年龄”和“性别”字段的表单。在您的step_3
方法中,您应该验证params[:age]
andparams[:gender]
是否通过并且是有效的,并且您还需要确保用户已经完成了步骤 1,以防止用户输入 URL 直接访问步骤 3。等等。
class Campaign < ActiveRecord::Base
with_options(:if => lambda { |campaign| campaign.on_or_past_step(:spam_can) }) do |spam_can|
spam_can.validates_associated :spam_can
spam_can.validates_presence_of :spam_can
end
def on_or_past_step
:
:
end
end
这是一项正在进行的工作,但我觉得我走在正确的轨道上。我正在使用AASM状态来确定要运行哪些验证。我还没有弄清楚路线应该如何工作,因为我所讨论的模型是一种资源。例如,哪组字段应该是编辑操作?