ruby 自定义验证失败,因为参数为空

qoefvg9y  于 2022-11-04  发布在  Ruby
关注(0)|答案(2)|浏览(173)

我有一个名为SocialNetwork的类,它有一个url和一个social_networks的枚举。我有一个根据所选的社交网络对url进行的正则表达式验证,但如果由于两个参数都为空而正在创建记录,则验证失败。

class SocialNetwork < ApplicationRecord
  REGEXP = {
    facebook: %r{\Ahttps://www.facebook.com/.+\z},
    twitter: %r{\Ahttps://twitter.com/.+\z},
    linkedin: %r{\Ahttps://www.linkedin.com/in/.+\z},
    github: %r{\Ahttps://github.com/.+\z},
    instagram: %r{\Ahttps://www.instagram.com/.+\z},
    youtube: %r{\Ahttps://www.youtube.com/.+\z},
    tiktok: %r{\Ahttps://www.tiktok.com/.+\z},
    twitch: %r{\Ahttps://www.twitch.tv/.+\z},
    onlyfans: %r{\Ahttps://onlyfans.com/.+\z}
  }.freeze

  belongs_to :user

  validates :url, presence: true
  validates :app, presence: true

  validates :app, uniqueness: { scope: :user_id }
  validate :url_match_regexp

  enum app: { facebook: 0, twitter: 1, instagram: 2, linkedin: 3, youtube: 4, tiktok: 5,
              twitch: 6, onlyfans: 7, github: 8 }

  private

  def url_match_regexp
    errors.add(:url, 'is not valid') unless url.match(REGEXP[app])
  end
end

如何在创建记录之前测试url_match_regexp

okxuctiv

okxuctiv1#

您已经验证了这些行中必须存在appurl

validates :url, presence: true
validates :app, presence: true

且如果它们不存在,则将出现有用错误消息。
这意味着在您的自定义验证方法中忽略这些情况是完全可以的,因为无论如何,用户都必须首先修复丢失的appurl
我可以通过将验证方法更改为以下方法来解决此问题:

def url_match_regexp
  return unless app && url

  errors.add(:url, 'is not valid') unless url.match?(REGEXP[app])
end
3yhwsihp

3yhwsihp2#

如果您希望在参数不为空时运行validate,请尝试以下操作:

validates :app, uniqueness: { scope: :user_id }, if: -> { app.present? }
validate :url_match_regexp, if: -> { app.present? && url_match_regexp.present? }

顺便说一句,

  • url.match(REGEXP[app])不会返回boolean =〉使用match?
  • url可以是任何类型(例如:数字)=〉使用to_s
  • app可以存在,但可能不在枚举列表中=〉应检查枚举列表中包含的app
validates :app, presence: true, inclusion: { in: apps.values }
...
url.to_s.match?(REGEXP[app])

相关问题