【问题标题】:has_one validates_associated firing inconsistently despite 'on: :create'has_one validates_associated 触发不一致,尽管 'on: :create'
【发布时间】: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

如果我取消注释 #&amp;&amp; parent.valid? 它会停止重定向,这看起来很疯狂。

发生这种情况的父母有一个无效的phone_number,但围绕phone_number 的要求在他们注册后发生了变化,所以我们不想为此而麻烦他们。所以期望的行为是让valid? 成为true,它最初只是在随后的调用中发生变化。

我已经添加了一些调试语句,我可以看到每次调用的验证上下文都是:update。所以它不应该运行validates_associated。这些也是创建的父母,所以不应该有:createnew_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


    【解决方案1】:

    如果不使用其他代码来判断,这很难。 @parent 和 parent 是否指向同一个对象?

    #&amp;&amp; parent.valid? 未注释时,结果会有所不同,这让我认为 @parent.valid? &amp;&amp; parent.valid? != @parent.valid?

    【讨论】:

    • 是的,很难知道要包含多少上下文。
    • 我的意思是到处写parent。这只是@parent 的 attr_reader,所以是的,它们是一样的。正如我所说,我可以在调试控制台中调用parent.valid? 两次(或@parent.valid? 两次),然后得到true 和false。即使在 :update 上下文中,什么可能导致它验证联系人?
    猜你喜欢
    • 2018-04-27
    • 2023-03-16
    • 2016-09-08
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多