Rails ActiveRecord关联模型的条件验证?

时间:2013-08-15 21:42:29

标签: ruby-on-rails ruby rails-activerecord

我有以下代码和“另存为草稿”功能,该功能应该阻止运行验证(即它们只应在状态不是草稿时运行)。我不确定如何在我的相关模型中接受这一点,以防止它们被验证:

class Proposal < ActiveRecord::Base

  belongs_to :user
  has_one :primary_presenter, dependent: :destroy

  validates :title,               presence: true
  validates :primary_presenter,   presence: true, unless: :draft?
  validates :abstract,            presence: true, unless: :draft?
  validates :description,         presence: true, unless: :draft?

  accepts_nested_attributes_for :primary_presenter

  def draft?
    status.draft?
  end
end


class Presenter < ActiveRecord::Base
  belongs_to :proposal

  validates :email,           presence: true, unless: :proposal_is_draft?
  validates :first_name,      presence: true, unless: :proposal_is_draft?
  validates :last_name,       presence: true, unless: :proposal_is_draft?
  validates :title,           presence: true, unless: :proposal_is_draft?

  def proposal_is_draft?
    proposal.status.draft?
  end
end

class PrimaryPresenter < Presenter
end

当然问题是当记录尚未保存时,presenter.proposal为nil。我已经查看了对于嵌套属性的reject_if :: all_blank,但是这似乎并不是我想要的,因为我仍然想要创建记录,即使它是空白的,所以当稍后编辑时,记录将存在。如果保存为草稿,我也想允许部分提交。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

不确定这是否足够,但有一种可能性是接受提案为零时,proposal_is_draft?实际上是真的。在这种情况下,您可以将其重新定义为:

def proposal_is_draft?
  !proposal.persisted? || proposal.draft?
end

虽然看起来看起来不太好,但是当提案未被持久化时它将返回true,并且当提案是草稿时返回true(从status.draft更改为使用您在Proposal类中定义的方法)。 / p>

答案 1 :(得分:0)

我个人从未真正使用过accepts_nested_attributes_for,但如果您愿意在reject_if上使用class Proposal < ActiveRecord::Base has_one :primary_presenter, dependent: destroy accepts_nested_attributes_for :primary_presenter, reject_if: primary_presenter_invalid? def primary_presenter_invalid?(attributes) return false if draft? [:email, :first_name, :last_name, :title].each do |attr| return true if attributes[attr].blank? end false end end ,则可以尝试为关联尝试“滚动自己”验证,而不是使用标准模型验证。父模型而不是直接验证子模型。

Presenter

然后我想删除{{1}}模型上的验证。虽然看起来您可能仍然想要这些,但是如果您通过任何方式创建或更新演示者,而不是通过提案上的嵌套属性?