views:

139

answers:

2

I have a simple model setup in my Ruby on Rails app. (User {name, username, lat, lon}) and am writing a basic extension to the model. I would like the method to return users within a certain distance. It all works just fine in the page view, but as I am debugging I would like to work through some testing using the script/console.

My question: It seems to be printing to the screen the entire result set when I run it from the command line and script/console.

My model:

class User < ActiveRecord::Base

  def distance_from(aLat, aLon)
    Math.sqrt((69.1*(aLat - self.lat))**2 + (49*(aLon - self.lon))**2 )
  end 


  def distance_from_user(aUser)
    distance_from(aUser.lat, aUser.lon)
  end

  def users_within(distance)
    close_users = []
    users = User.find(:all)
    users.each do |u|
        close_users << u if u.distance_from_user(self) < distance
    end
    return close_users
  end
end 

and from the command line I am running

>> u = User.find_by_username("someuser")
>> print u.users_within(1)

So, I guess I would like to know why it's printing the whole result set, and if there is a way to suppress it so as to only print what I want?

A: 

you should handle it using a mysql query. it's not good practise to pull all data from the database perofrm on them and show top 10 data out of them. do something like following.

User.find_by_sql("select u.*, 
          (((69.1*(aLat - self.lat))**2 + (49*(aLon - self.lon))**2 ) < 100")) as distance
          from users u
          where u.username='someuser' and
          distance > 100 order by distance DESC LIMIT 10)

Above query is just an example but it's always good practice to do something like above.

Salil
I know that is generally the case. In fact I have done load testing with varying recordset sizes up to a 50M or so users. In PHP the performance is about 1:3 between sql vs server script. There are often circumstances where the best way to do the comparison is within the method. So, my question still stands, why does it print all the results to the screen
Lloyd
A: 

It appears that the console interface of the Ruby application evaluates each line as though it were entered from the console.

I would have expected it to some encapsulation of the scripts but it makes sense as it is being interpreted on the fly by the ruby interactive console line.

And to clarify as to the prefered sql base solution, doing find_by_sql is frowned upon in most refereces I have found. The SQL based solution that I reccomend is

def f
  User.find(:all, :conditions => ["sqrt(pow(69.1*(lat - ?),2) + pow(49*(lon - ?),2)) < 1", lat.to_s,lon.to_s])
end
Lloyd