6ft Dan
6ft Dan

Reputation: 2445

Rails validation of exclusion of partial string from list

Basically I want to validate that the url provided does not include yahoo, goolge, twitter, or facebook, I was really trying to complete this with an inline lambda. But each test I do has either raised an error, or did not block the word from the list.

I've tried each of the following... and others...

validates_exclusion_of :url, in: %w[twitter google facebook yahoo]

validates_exclusion_of :url, with: ->(link) {%w[twitter google facebook yahoo].all?{ |x| !!link[x] } }

validates_exclusion_of :url, in: ->(link) {%w[twitter google facebook yahoo].all?{ |x| !!link[x] } }

validates :url, exclusion: { in: %w[twitter google facebook yahoo]

validates ->(:url){ %w[twitter google facebook yahoo].any? {|y| !!:url[y]}.(:url)

validates :url, :with lambda { %w[twitter google facebook yahoo].any? { |y| !!:url[y] } }

validates :url, with: (not %w[twitter google facebook yahoo].any?{|y|if(:url.nil?)false;end;!!:url[y]})

validates :url, with: (not %w[twitter google facebook yahoo].any?{ |y| :url.nil? ? false : !!:url[y] })

validates :url, with: (not %w[twitter google facebook yahoo].any?{ |y| (not !!:url) ? false : !!:url[y] })

validates :url, with: (not %w[twitter google facebook yahoo].any?{ |y| !!defined?(:url) && not :url.nil? ? false : !!:url[y] })

validates :url, with: (not (%w[twitter google facebook yahoo]).any?{ |y| defined?(:url) ? false : :url[y] })

validates_with (not (%w[twitter google facebook yahoo]).any?{ |y| defined?(:url) ? false : :url[y] })

What lambda and validator helper would work for for this?

Upvotes: 0

Views: 899

Answers (4)

Sully
Sully

Reputation: 14943

You can achieve that with Regex

validates_format_of :url, :with => /^((?!(google.com|yahoo.com|twitter.com|facebook.com)).)*$/

Will catch:

"www.mail.google.com"        --> catch
"www.mail.yahoo.com"         --> catch
"domain.twitter.com"         --> catch
"twitter.com"                --> catch
"www.twitter.com"            --> catch
"data.facebook.com"          --> catch
"www.firstfighterwing.com"   --> free

Explaination:

\A((?!(google.com|yahoo.com|twitter.com|facebook.com)).)*\z
|  ||           |                                    | |
|  ||           OR                                   | |
Beg||ning of line                                    | |
   ||                                                | |
   Look-ahead not (google.com|yahoo.com ...)         | |
                                                     Followed by any characters but \n 

Upvotes: 4

Max Williams
Max Williams

Reputation: 32945

Using the standard validation helpers for this is awkward because they'll only let you match against a fixed set of strings, or test if it DOES match a regex if you use validates_format_of. You need to test if it DOES NOT match a regex. (you could set up a regex which tests if the string doesn't contain any of the values, but this is awkward and ugly to do with a regex - it's much nicer and more readable to use a regex which tests if the string does contain the values)

I would use a custom validation method for this.

validate :url_does_not_contain_unwanted_string

def url_does_not_contain_unwanted_string
  if self.url =~ /twitter|google|facebook|yahoo/
    self.errors.add(:url, "contains a string which is not allowed")
  end
end

Upvotes: 1

Himesh
Himesh

Reputation: 646

This can be done with

validates_exclusion_of :url, in: ['twitter', 'google', 'yahoo', 'facebook']

Hope this helps :)

Upvotes: 0

Pavan
Pavan

Reputation: 33542

This should work

validates_exclusion_of :url, in: %w(twitter google facebook yahoo)

You have given validates_exclusion_of :url, in: %w[twitter google facebook, yahoo] which is wrong because you have a comma(,) in the pair of words which is a wrong syntax.

%w(twitter google facebook yahoo)
#=> ["twitter","google","facebook","yahoo"]

Upvotes: 1

Related Questions