Rails - 验证两个 own_to 列之一是否存在

问题描述 投票:0回答:1

我有一个名为 Log 的模型,它与 ButtonPress 和 LinkClick 两个模型有关系。我需要验证其中任何一个的存在(出于分析原因,我需要在不使用多态关系的情况下执行此操作)

我的规格文件如下:

RSpec.describe RedirectLog, type: :model do
  it { is_expected.to belong_to(:button_press).optional }
  it { is_expected.to belong_to(:link_click).optional }

  it "has either a button_press or a link_click" do
    log = build(:log, button_press: nil, link_click: nil)
    expect(log).not_to be_valid
  end

结束

为了实现这一目标,我创建了如下模型:

class Log < ApplicationRecord
  belongs_to :button_press, optional: true
  belongs_to :link_click, optional: true

  validates :button_press, presence: true, unless: :link_click
end

当我运行此程序时,出现以下错误:

Failure/Error: it { is_expected.to belong_to(:button_press).optional }
       Expected Log to have a belongs_to association called button_press (and for the record not to fail validation if :button_press is unset; i.e., either the association should have been defined with `optional: true`, or there should not be a presence validation on :button_press)

所以简而言之,如果我想验证它的存在,即使是有条件的,我也不能拥有belongs_to关联。我的问题是,Rails 的方法是什么,可以在不使用多态性的情况下对两个 own_to 列之一进行验证?

ruby-on-rails rspec
1个回答
3
投票

一种方法是使用自定义验证器。我会用自己的文件等使其完全正式,但为了概念验证,您可以这样做:

class Log < ApplicationRecord

  ###################################################################
  #
  # Associations
  #
  ###################################################################
  belongs_to :button_press, optional: true
  belongs_to :link_click,   optional: true



  ###################################################################
  #
  # Validations
  #
  ###################################################################
  validate :button_press_or_link_click_presence



  ###################################################################
  #
  # In-Model Custom Validators (Private)
  #
  ###################################################################
  def button_press_or_link_click_presence
    self.errors.add(:base, 'Either a Button Press or a Link Click is required, but both are missing.') if button_press.blank? && link_click.blank?
  end
  private :button_press_or_link_click_presence
end
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.