0

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?

2
  • Why don't you use validates_format_of? Validate it with regex Commented May 29, 2014 at 13:53
  • I've seen that, but I haven't seen it used with a list. It works with strings and regexs... but lists? Commented May 29, 2014 at 13:54

4 Answers 4

4

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 
Sign up to request clarification or add additional context in comments.

2 Comments

Rails warned me of (^ or $), which may present a security risk. Did you mean to use \A and \z I switched out ^ for \A and $ for \z and it works! Thanks!
Glad to know it works. I do not have a ruby/rails enviroment at work so I only tested it in JS
1

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"]

4 Comments

%w allows any pair of symbols. You can even do %w#twitter google facebook yahoo#
@6ftDan But you have given like this %w[twitter google facebook, yahoo] with a comma which should be a syntax error.
@6ftDan And also http://mail.google.com will not work in your case.You have to clarify your question.
Thanks for pointing out the comma. That was an obvious oversight. I didn't use the comma in the code. As I was copying and pasting a few didn't include yahoo so I quickly threw it in the question with the comma.
1

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

2 Comments

Thanks for this. I've learned a few things from your explanation. Using self.url has helped me realize the scope. I may definitely use this in future cases.
Np. The correct answer shows how to set up a regex which does what you want: chances are that A) you have learned something about regexes but B) you don't fully understand what's going on in that regex. This is sort of my point about "awkward and ugly". If you're totally cool with what's happening in that regex then great :)
0

This can be done with

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

Hope this helps :)

1 Comment

@MaxWilliams Sorry for that. Typed in a bit hurry. Rectified. Thanks for notifying :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.