【发布时间】:2011-08-23 22:05:48
【问题描述】:
我正在用 Rails 编写向导表单;例如一个模型对象的多个输入页面。
我的方法的基础是 Ryan Bates 的 Multistep form railscast 中描述的那些:http://railscasts.com/episodes/217-multistep-forms(如果有人想知道下面某些代码背后的原因)。
这里审查的对象是“参与者”,它有一个“地址”
我的问题是,当用户试图通过地址输入屏幕时,我只想验证嵌套对象(地址)。这目前通过 Participant 模型上名为“current_step”的属性进行跟踪
所以我有一个参与者:
class Participant < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address
validates_presence_of :first_name, :last_name, :if => self.current_step == "name"
...
def steps = %w[ name address confirm ] # the steps the wizard will follow
end
还有地址:
class Address < ActiveRecord::Base
belongs_to :participant
validates_presence_of :address1, :state, :suburb, :postcode #, :if => participant.current_step == "address"
end
这种方法的原理是在控制器(未显示)上为向导的每个步骤调用“创建”操作,并且在处理每个步骤时它只验证模型的一个子集。
目前,当我完成第一个屏幕(“姓名”)并尝试进入地址步骤时,地址验证被触发,我被发送回“姓名”屏幕,显示空白地址详细信息的验证错误.
所以我在这里尝试了多种方法,其中最后一部分是上面显示的地址验证的注释掉条件 - 我发现这不起作用,因为我只是在构建 Participant->Address 对象,但不保存它们。因此@participant.address 为我获取地址对象,但@participant.address.participant 为空,因为地址还没有用于查找其父对象的participant_id 外键。
我挣扎的原因似乎是包含了超级方便的accepts_nested_attributes_for 方法。我期待使用validates_associated 进行验证,但我看到accepts_nested_attributes_for 标记既能很好地传播表单参数以创建嵌套模型对象,又能确保participant#valid? 方法调用到地址验证所有情况。
所以我的困境是如何最好地使用participant#valid? 方法来验证部分完整的模型,基于参与者中的current_step 参数?
编辑 - 更新以删除额外信息,并提炼到核心问题
【问题讨论】:
-
只是猜测,但您是否尝试过验证 :address, :if => Proc.new {|participant|参与者.current_step == '名称' }
-
我尝试的第一件事 - 但如上所述(也许不太清楚,我承认)地址对象在保存之前没有参与者,所以我在 nil 上调用 current_step 时出错类。
-
将 :inverse_of 添加到您的关系中,因此地址对象在构建时将具有对其参与者的引用。
标签: ruby-on-rails ruby ruby-on-rails-3 validation activerecord