Archive for the ‘Vacations’ Category

Smart Searching Using Anonymous Scopes

Sunday, June 21st, 2009

I really like how Lovetastic’s search works.  Instead of a plethora of select boxes, users can simply use expressions to create searches.  We did something similar with Tryst’s searching.  One text field and you enter stuff like age ranges (30-45), things like smoke-yes or smoke-no, cities, zipcodes, etc.

Tryst.com Search

To make this whole thing more Rails like, I did not want to just use Regex to parse out search terms and plug them into a complicated SQL query.  That would be soooooo PHP.

Named Scopes are awesome.  You can use them to built decently formatted and fairly complicated SQL queries in a nice, no bullshit, manner. You can do cool stuff like this:

@users = User.active.males.in_zipcode(params[:zip_code]).nonsmokers.top_ten

Just keep stacking scopes on.  Rails generates the query and it usually doesn’t suck.

Go read the API docs for the basics on Named Scopes. We’re gonna do some not basic stuff. Check out Ryan Bate’s Anonymous Scopes Railscast, which introduced me to this method of generating Scopes.

We wanted to add a Class Method called search and have it define the Scopes. We pass in the params hash, anything else we need (like the current user), and let it handle the Scoping and determining what we’re looking for from the search params.

To start, here is our search class method.

# app/models/user.rb
 def self.search(params, current_user)
    page = params[:page] || 1
    search_terms = params[:search]
end

Yeah, using Will Paginate and assigning my search terms to a local variable. I’ve also written another Class Method that does the parsing of the params.

# app/models/user.r.b
def self.search(params, current_user)
    page = params[:page] || 1
    search_terms = params[:search]
   #parse params
    max_age, min_age, zip_codes, gender, smoke, drink = self.get_parameters(search_terms.to_s, current_user)
  end

Now, we’re going to define some dynamic scopes. This is awesome. For it to work, we’ll add an initializer.

#config/initializers/scopes.rb

class ActiveRecord::Base
  named_scope :conditions, lambda { |*args| {:conditions => args} }
end

Now, lets make the scopes.

def self.search(params, current_user)
    page = params[:page] || 1
    search_terms = params[:search]

    max_age, min_age, zip_codes, gender, smoke, drink = self.get_parameters(search_terms.to_s, current_user)

    scope = User.scoped({})
    scope = scope.conditions "users.age >= ? and users.age <= ?", min_age, max_age unless min_age.blank?
    scope = scope.conditions "users.zip_code in (?)", zip_codes unless zip_codes.blank?
    scope = scope.conditions "users.smoker = ?", smoke unless smoke.blank?
    scope = scope.conditions "users.drink = ?", drink unless drink.blank?
    scope = scope.conditions "users.gender = ?", gender unless gender.blank?
    scope.paginate :page => page, :order => "created_at DESC"
  end

Pretty slick, huh? So now, in my controller I just need

# app/controllers/search.rb
def users
    @users = User.search(params, current_user)
end

Assuming your class method for parsing out scope parameters doesn’t suck, you should have very clean, cuddly, and concise searching. No more worrying about breaking some huge crappy SQL query.

You’ll notice I used

users.zip_codes in (?)

This is because I can pass an array of zipcodes and return all the users in those zipcodes. This is because I’ve implemented radial distance searching base on zipcodes. Users can search like ” 60606 25miles” and return all users who are within 25 miles of 60606. We’ll go into how this works in the next post.

rentalrundown.com and Seattle trip

Monday, June 9th, 2008

Two things…

First - Jen and I are taking a trip to Seattle for 7 days starting this Saturday.  We’re super pumped.  

Second – Over Christmas last year I started on this lil Rails app I was calling duluthrentalreview.com.  Pretty obvious what it was.  I get so pissed at landlords in this town, and even more pissed at my fellow renters for putting up with the crap quality of said rentals.  The problem is this:  Landlords in this town do not keep up their rentals because renters do not demand that they are nice and decent and that the landlords keep them up.  You get the idea. 

Ok, so yeah I started writing this rental review site over christmas, got like halfway though it and just didn’t have time to finish it.. till now.  I re-wrote almost all of it, convertging it to REST.   I’m gonna try to continue updating it over the next couple days till our trip.  Oh, ad the url changed from duluthrentalreview.com to rentalrundown.com… liked the sound of rentalrundown better.

 

Trip to Seattle & Washington State

Thursday, May 22nd, 2008

Just booked a little week long excursion to Washington State for next month.  We’re flying in to Seattle on June 14th and will be returning on 21st.  Should be super sweet, the Pacific Northwest is my favorite region of The States and its been about 6-7 years since I’ve been out there.

Jen’s never been there before, so I’m very sure her mind will be blown.  The tentative itinerary is 2-3 days in Seattle, 1 day for The Olympic Nat’l Park/Washington Coastline, and a day for a quick Portland/Mt. St. Helen’s trip.  Maybe only 2 days in Seattle and another day split between Mt. St. Helen’s and Mt. Rainier and a full day for Portland… hell, we don’t know maybe we’ll just see what we feel like doing, thats what we usually end up doing on vacations.  For our trip to Florida, we literally had no plan except to go to Florida and went with the flow the whole time and it was great.

I’d also like to go out to Spokane and visit some relatives, we’ll have to see.. so much to do so little time.

I’ll for sure be posting some pics when we get back…