【发布时间】:2015-08-06 06:06:25
【问题描述】:
在具有validates_associated :contact, on: :create 的模型上检查valid? 时,我看到了非常奇怪的行为。如果我两次调用valid?,第一个是true,第二个是false。
这是模型的最小版本,希望它足够详细:
class Parent < ActiveRecord::Base
has_one :contact
accepts_nest_attributes_for :contact
validates_presence_of :contact
validates_associated :contact, on: :create
delegate :postcode,
:phone_number,
to: :contact
end
class Contact < ActiveRecord::Base
belongs_to :parent
belongs_to :country
validates_format_of :phone_number, if: :logged_in_australian?, allow_blank: true
validates_format_of :postcode, if: :logged_in_australian?, allow_blank: true
private
def logged_in_australian?
logged_in? && australian?
end
def logged_in?
current_user && current_user == user
end
def australian?
country && country.name == 'Australia'
end
end
我在控制器中看到的行为是两个动作之间的无限重定向:
def dashboard
flash.keep if !parent.valid?
return redirect_to complete_signup_parent_path if !parent.valid?
# other stuff
end
def complete_signup
return redirect_to action: "dashboard" if parent.valid? #&& parent.valid?
# other stuff
end
如果我取消注释 #&& parent.valid? 它会停止重定向,这看起来很疯狂。
发生这种情况的父母有一个无效的phone_number,但围绕phone_number 的要求在他们注册后发生了变化,所以我们不想为此而麻烦他们。所以期望的行为是让valid? 成为true,它最初只是在随后的调用中发生变化。
我已经添加了一些调试语句,我可以看到每次调用的验证上下文都是:update。所以它不应该运行validates_associated。这些也是创建的父母,所以不应该有:create 或new_record? 在玩。另一个调试语句证明正在对联系人进行验证,包括对 phone_number 的验证,但只是在操作中第二次调用它。
我还设置了一个断点,可以看到 parent.valid? 返回 true 然后返回 false,而且如果我在调用 valid? 之前中断并调用 parent.contact_detail 然后调用 parent.valid? 然后它返回 false。
为什么对parent.valid? 的第二次调用会验证contact,即使它只应该这样做on: :create?
【问题讨论】:
标签: ruby-on-rails ruby validation has-one validates-associated