2012-08-01 56 views
1

如果我在Rails中有两个URL(无论它们是字符串形式还是URI对象),确定它们是否相等的最好方法是什么?这似乎是一个相当简单的问题,但即使其中一个URL是相对的,另一个是绝对的,或者其中一个URL的参数不同于其他参数,我也需要解决方案。在Rails中,我如何确定两个URL是否相等?

我已经看过What is the best way in Rails to determine if two (or more) given URLs (as strings or hash options) are equal?(和其他几个问题),但问题很老,建议的解决方案无法按照我需要的方式工作。

+0

那么,什么是你想要的方式?它何时应该返回真实?只需检查控制器和操作? – 2012-08-01 13:56:06

+0

@AnthonyAlberto我想我的原始问题是要求一个更通用的解决方案,它将采用任何两个URL(即使它们指的是外部站点上的页面),并检查它们是否引用同一页面。想想看,虽然只是检查控制器和行动实际上对我来说很好。 – Ajedi32 2012-08-01 14:36:05

+0

但它是在你的应用程序的上下文吗?或者你需要测试任何网址? – 2012-08-01 14:40:44

回答

4

只要你有URL1和URL2是含有URL一些字符串:

def is_same_controller_and_action?(url1, url2) 
    hash_url1 = Rails.application.routes.recognize_path(url1) 
    hash_url2 = Rails.application.routes.recognize_path(url2) 

    [:controller, :action].each do |key| 
    return false if hash_url1[key] != hash_url2[key] 
    end 

    return true 
end 
+0

太好了,那正是我需要的!谢谢你的帮助。 – Ajedi32 2012-08-01 15:04:47

0

结帐的addressable宝石并且具体地normalize方法(及其documentation)和heuristic_parse方法(及其documentation)。我过去使用过它,发现它非常强大。

寻址即使处理Unicode字符的URL在其中:

uri = Addressable::URI.parse("http://www.詹姆斯.com/") 
uri.normalize 
#=> #<Addressable::URI:0xc9a4c8 URI:http://www.xn--8ws00zhy3a.com/> 
3

1)转换网址canonical form

在我目前的项目我使用addressable宝石为了做到这一点:

def to_canonical(url) 
    uri = Addressable::URI.parse(url) 
    uri.scheme = "http" if uri.scheme.blank? 
    host = uri.host.sub(/\www\./, '') if uri.host.present? 
    path = (uri.path.present? && uri.host.blank?) ? uri.path.sub(/\www\./, '') : uri.path 
    uri.scheme.to_s + "://" + host.to_s + path.to_s 
rescue Addressable::URI::InvalidURIError 
    nil 
rescue URI::Error 
    nil 
end 

例如:

> to_canonical('www.example.com') => 'http://example.com' 
> to_canonical('http://example.com') => 'http://example.com' 

2)比较你的网址:canonical_url1 == canonical_url2

UPD:

  • Does it work with sub-domains? - 不,我的意思是,我们不能说translate.google.comgoogle.com是相等的。当然,你可以根据你的需要修改它。
+0

这将工作与子域?如何使用[addressabler](https://github.com/flipsasser/addressabler)gem来检查子域是否存在,如果不是,则将其强制为* www * * – stephenmurdoch 2012-08-01 14:59:06

+0

这看起来很棒,但是您提供的方法不会与相关网址一起工作:'to_canonical('/ test')=>“http:/// test”' 可寻址的gem看起来与我在这里要做的事情非常相关。 – Ajedi32 2012-08-01 15:09:43

+0

@stephenmurdoch我已经更新了我的答案。至于寻址宝石,它似乎并不是非常积极的维护。 – melekes 2012-08-01 15:10:29

相关问题