B30ce50678f0e934eaa6697425c59dd7

Hi!
I've a got a website ActiveRecord object, with a url field. I want to allow my users to perform searches by url. The problem is that it happens all the time that my user will not type the full url... Basically, I want my find_by_url method to return "http://www.apple.com" when users type in :
- http://apple.com
- http://www.apple.com
- http://www.apple.com/
- http://apple.com/

Currently, I am only saving the "full" version in the database : http://www.apple.com/ and my first try is very bad!
I am sure it can be a lot better, with only one SQL request!

# This method searches a source by  the http, the www and the trailing / to a url
	def self.find_by_url(url)
		Source.find :first, :conditions => [ " url = ? OR url = ? OR url = ? OR url = ? ", url, url.gsub("http://", "http://www"), url + "/", url.gsub("http://", "http://www")+"/"] 
	end

Refactorings

No refactoring yet !

F288a8afe5302a16a366d5e9d34f2fec

Joe Grossberg

July 18, 2008, July 18, 2008 21:42, permalink

No rating. Login to rate!

I wouldn't make the query do that work. Instead, sanitize the data and the user input, in the same way -- by stripping off any leading "http://", "https://" and/or "www."

F288a8afe5302a16a366d5e9d34f2fec

Joe Grossberg

July 18, 2008, July 18, 2008 21:43, permalink

No rating. Login to rate!

I wouldn't make the query do that work. Instead, sanitize the data and the user input, in the same way -- by stripping off any leading "http://", "https://" and/or "www."

2fa67a053f1bb83dca069df3c9f51a8a

lel

July 18, 2008, July 18, 2008 23:54, permalink

No rating. Login to rate!

Naming the method find_by_url() overrides the dynamic attribute finder, which could confuse people since it won't do what it would by default. And if using the dynamic finder find_by_url_and_rating(), (if there is a rating column) your own implementation in find_by_url will not be used and confuse even more.
I think it is better to name it different to reflect that it is a home brew find_by--- with a twist.

The following is not perfect, but maybe helpful:

def self.find_by_url_like(url)
  # make sure url has a scheme before URI parses
  uri = url.match(/^https?:\/\//) ? URI.parse(url) : URI.parse("http://#{url}") 
  # % is wildcard, so http://*.abc.com will match http://www.abc.com, but also http://www.news.abc.com
  find(:first, :conditions => ["url LIKE ?", "#{uri.scheme}://%.#{uri.host}"])
rescue URI::InvalidURIError
  nil
end

Your refactoring





Format Copy from initial code

or Cancel