Home > OS >  Custom Validation fails because params are nil
Custom Validation fails because params are nil

Time:10-28

i have a Class called SocialNetwork with an url and an enum of social_networks. I have a regexp validation of the url depending on the social network selected, but it fails if the record is being created due to the fact that both params are nil.

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

How can i test url_match_regexp before the record being created?

CodePudding user response:

if you want run validate when params are not nil, try this:

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

btw,

  • url.match(REGEXP[app]) won't return boolean => use match?
  • url can be any type (example: number) => use to_s
  • app can be present but it may not in enum list => should check app included in enum list
validates :app, presence: true, inclusion: { in: apps.values }
...
url.to_s.match?(REGEXP[app])

CodePudding user response:

You already verify that app and url must be present in these lines

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

and if they are not present, then there will be a useful error message.

This means it is would be totally fine to just ignore those cases in your custom validation method, because the user would have to fix the missing app and url first anyway.

I would fix this problem by just changing the validation method to this:

def url_match_regexp
  return unless app && url

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