Add http(s) to URL if it's not there?

前端 未结 7 1937
抹茶落季
抹茶落季 2020-12-08 19:27

I\'m using this regex in my model to validate an URL submitted by the user. I don\'t want to force the user to type the http part, but would like to add it myself if it\'s n

相关标签:
7条回答
  • 2020-12-08 19:41

    The accepted answer is quite okay. But if the field (url) is optional, it may raise an error such as undefined method + for nil class. The following should resolve that:

    def smart_add_url_protocol
      if self.url && !url_protocol_present?
        self.url = "http://#{self.url}"
      end
    end
    
    def url_protocol_present?
      self.url[/\Ahttp:\/\//] || self.url[/\Ahttps:\/\//]
    end
    
    0 讨论(0)
  • 2020-12-08 19:43

    Use a before filter to add it if it is not there:

    before_validation :smart_add_url_protocol
    
    protected
    
    def smart_add_url_protocol
      unless self.url[/\Ahttp:\/\//] || self.url[/\Ahttps:\/\//]
        self.url = "http://#{self.url}"
      end
    end
    

    Leave the validation you have in, that way if they make a typo they can correct the protocol.

    0 讨论(0)
  • 2020-12-08 19:44

    Using some of the aforementioned regexps, here is a handy method for overriding the default url on a model (If your ActiveRecord model has an 'url' column, for instance)

    def url
      _url = read_attribute(:url).try(:downcase)
      if(_url.present?)
        unless _url[/\Ahttp:\/\//] || _url[/\Ahttps:\/\//]
          _url = "http://#{_url}"
        end
      end
    _url
    end
    
    0 讨论(0)
  • 2020-12-08 19:49

    Don't do this with a regex, use URI.parse to pull it apart and then see if there is a scheme on the URL:

    u = URI.parse('/pancakes')
    if(!u.scheme)
      # prepend http:// and try again
    elsif(%w{http https}.include?(u.scheme))
      # you're okay
    else
      # you've been give some other kind of
      # URL and might want to complain about it
    end
    

    Using the URI library for this also makes it easy to clean up any stray nonsense (such as userinfo) that someone might try to put into a URL.

    0 讨论(0)
  • 2020-12-08 19:52

    I wouldn't try to do that in the validation, since it's not really part of the validation.

    Have the validation optionally check for it; if they screw it up it'll be a validation error, which is good.

    Consider using a callback (after_create, after_validation, whatever) to prepend a protocol if there isn't one there already.

    (I voted up the other answers; I think they're both better than mine. But here's another option :)

    0 讨论(0)
  • 2020-12-08 19:58

    Based on mu's answer, here's the code I'm using in my model. This runs when :link is saved without the need for model filters. Super is required to call the default save method.

    def link=(_link)
        u=URI.parse(_link)
    
        if (!u.scheme)
            link = "http://" + _link
        else
            link = _link
        end
        super(link)
    end
    
    0 讨论(0)
提交回复
热议问题