尽管'on :: create',has_one validates_associated触发不一致

时间:2015-08-06 06:06:25

标签: ruby-on-rails ruby validation has-one validates-associated

在具有valid?的模型上检查validates_associated :contact, on: :create时,我看到了非常奇怪的行为。如果我拨打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。这些也是父母创建的,因此不应该有:createnew_record?。另一个调试语句证明验证是在联系上运行的,包括phone_number的验证,但只是第二次在操作中调用。

我还输入了一个断点,可以看到parent.valid?返回true然后返回false,并且如果我在调用valid?之前中断并调用parent.contact_detail然后{{1}然后它返回false。

为什么第二次调用parent.valid?验证parent.valid?,即使它只应该contact呢?

1 个答案:

答案 0 :(得分:0)

在没有其余代码的情况下告诉它很难。 @parent和parent是否指向同一个对象?

#&& parent.valid?取消注释后,结果会有所不同,这让我认为@parent.valid? && parent.valid?!= @parent.valid?