English 中文(简体)
如果没有,可加到URL?
原标题:Add http(s) to URL if it s not there?

我在模型中利用这一分类法验证用户提交的URL。 我不想强迫用户打上“http://un.org”部分,但如果它没有的话,我想补充一下。

validates :url, :format => { :with => /^((http|https)://)?[a-z0-9]+([-.]{1}[a-z0-9]+).[a-z]{2,5}(:[0-9]{1,5})?(/.)?$/ix, :message => " is not valid" }

任何想法,我如何能够做到这一点? 我在鉴定和监管方面几乎没有经验。

最佳回答

a. 如果没有,则使用前过滤器添加:

before_validation :smart_add_url_protocol

protected

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

如果鉴定人打上了打字,他们就可以纠正协议。

问题回答

Don t do this with a regex, use URI.parse , 将其分开,然后看看是否有关于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.

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

Preface, justification and how it should be done

当有人在“打字”前在“打字<>/代码>上改变模型时,我对此表示仇恨。 几天后,出于某种原因,模型必须保持(有效日期:虚假),但有些过滤器却总是在指定领域运行,因此无法运行。 当然,数据无效通常是你想要避免的,但如果使用这种数据,则不需要这种选择。 还有一个问题是,每当你要求一个模型时,这些修改也是有效的。 简单地询问某一模式是否有效,可能会导致模型得到修改,这一事实只是意想不到的,甚至可能不希望。 如果我不得不选择一个标题I(d)至,然后再选择<0>/code>。 然而,由于我们为我们的模式提供预议意见,而这将打破世界投资倡议在预审中的地位,因为 h永远不会被叫。 因此,我决定最好把这个概念分离到单元或关切中,并为人们适用“钥匙拼凑”,确保改变田地价值时总是通过过滤器进行,如果缺少一个缺省规程,则会增加违约规程。

The module

#app/models/helpers/uri_field.rb
module Helpers::URIField
  def ensure_valid_protocol_in_uri(field, default_protocol = "http", protocols_matcher="https?")
    alias_method "original_#{field}=", "#{field}="
    define_method "#{field}=" do |new_uri|
      if "#{field}_changed?"
        if new_uri.present? and not new_uri =~ /^#{protocols_matcher}:///
          new_uri = "#{default_protocol}://#{new_uri}"
        end
        self.send("original_#{field}=", new_uri)
      end
    end
  end
end

In your model

extend Helpers::URIField
ensure_valid_protocol_in_uri :url
#Should you wish to default to https or support other protocols e.g. ftp, it is
#easy to extend this solution to cover those cases as well
#e.g. with something like this
#ensure_valid_protocol_in_uri :url, "https", "https?|ftp"

As a concern

If for some reason, you d rather use the Rails Concern pattern it is easy to convert the above module to a concern module (it is used in an exactly similar way, except you use include Concerns::URIField:

#app/models/concerns/uri_field.rb
module Concerns::URIField
  extend ActiveSupport::Concern

  included do
    def self.ensure_valid_protocol_in_uri(field, default_protocol = "http", protocols_matcher="https?")
      alias_method "original_#{field}=", "#{field}="
      define_method "#{field}=" do |new_uri|
        if "#{field}_changed?"
          if new_uri.present? and not new_uri =~ /^#{protocols_matcher}:///
            new_uri = "#{default_protocol}://#{new_uri}"
          end
          self.send("original_#{field}=", new_uri)
        end
      end
    end
  end
end

P.S. The above approaches were tested with Rails 3 and Mongoid 2.
P.P.S If you find this method redefinition and aliasing too magical you could opt not to override the method, but rather use the virtual field pattern, much like password (virtual, mass assignable) and encrypted_password (gets persisted, non mass assignable) and use a sanitize_url (virtual, mass assignable) and url (gets persisted, non mass assignable).

根据 mu回答,这里使用的是我模式中的Im。 运行时间:不需要模型过滤器便可节省连接。 上级必须使用缺省储蓄方法。

def link=(_link)
    u=URI.parse(_link)

    if (!u.scheme)
        link = "http://" + _link
    else
        link = _link
    end
    super(link)
end

采用上述某些标准,这里是一种手法,用以在模型上超越缺省(如果您的活记录模式有一栏,例如)

def url
  _url = read_attribute(:url).try(:downcase)
  if(_url.present?)
    unless _url[/Ahttp:///] || _url[/Ahttps:///]
      _url = "http://#{_url}"
    end
  end
_url
end

我不得不就同一模式的多个栏目发言。

  before_validation :add_url_protocol

  def add_url_protocol
    [
      :facebook_url, :instagram_url, :linkedin_url,
      :tiktok_url, :youtube_url, :twitter_url, :twitch_url
    ].each do |url_method|
      url = self.send(url_method)

      if url.present? && !(%w{http https}.include?(URI.parse(url).scheme))
        self.send("#{url_method.to_s}=",  https:// .concat(url)) 
      end
    end
  end

我不想在验证中这样做,因为它实际上不是验证的一部分。

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

考虑使用背书( After_create , after_validation/ , whatever)预先批准议定书。

(我对其他答复进行了表决;我认为,这些答复比我们好。) 但这里还有另一种选择:





相关问题
rails collection_select vs. select

collection_select and select Rails helpers: Which one should I use? I can t see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a ...

SSL slowness in EC2

We ve deployed our rails app to EC2. In our setup, we have two proxies on small instances behind round-robin DNS. These run nginx load balancers for a dynamically growing and shrinking farm of web ...

Auth-code with A-Za-z0-9 to use in an URL parameter

As part of a web application I need an auth-code to pass as a URL parameter. I am currently using (in Rails) : Digest::SHA1.hexdigest((object_id + rand(255)).to_s) Which provides long strings like : ...

RubyCAS-Client question: Rails

I ve installed RubyCAS-Client version 2.1.0 as a plugin within a rails app. It s working, but I d like to remove the ?ticket= in the url. Is this possible?

activerecord has_many :through find with one sql call

I have a these 3 models: class User < ActiveRecord::Base has_many :permissions, :dependent => :destroy has_many :roles, :through => :permissions end class Permission < ActiveRecord::...

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

Text Editor for Ruby-on-Rails

guys which text editor is good for Rubyonrails? i m using Windows and i was using E-Texteditor but its not free n its expired now can anyone plese tell me any free texteditor? n which one is best an ...

How to get SQL queries for each user where env is production

I’m developing an application dedicated to generate statistical reports, I would like that user after saving their stat report they save sql queries too. To do that I wrote the following module: ...