Ajedi32
Ajedi32

Reputation: 48368

In Rails, how do I determine if two URLs are equal?

If I have two URLs in Rails, (whether they be in string form or URI objects) what's the best way to determine if they are equal? It seems like a fairly simple problem, but I need the solution to work even if one of the URLs is relative and the other is absolute, or if one of the URLs has different parameters than the other.

I already looked at What is the best way in Rails to determine if two (or more) given URLs (as strings or hash options) are equal? (and several other questions), but the question was pretty old and the suggested solution doesn't work the way I need it to.

Upvotes: 1

Views: 1534

Answers (3)

melekes
melekes

Reputation: 1888

1) convert URL to canonical form

In my current project I am using addressable gem in order to do that:

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

Example:

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

2) compare your URLs: canonical_url1 == canonical_url2

UPD:

  • Does it work with sub-domains? - No. I mean, we cannot say that translate.google.com and google.com are equal. Of course, you can modify it depending on your needs.

Upvotes: 3

Anthony Alberto
Anthony Alberto

Reputation: 10395

Provided you have url1 and url2 being some string containing a 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

Upvotes: 4

Chris Salzberg
Chris Salzberg

Reputation: 27374

Checkout the addressable gem and specifically the normalize method (and its documentation), and the heuristic_parse method (and its documentation). I've used it in the past and found it to be very robust.

Addressable even handles URLs with unicode characters in them:

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

Upvotes: 0

Related Questions