用户模型中的NoMethodError未定义方法

时间:2013-09-17 19:46:06

标签: ruby-on-rails

在控制台中运行'user.within_miles(25).count(:all)'时出现错误,未定义方法`area_for'。我认为我的范围是错误的,这导致了这个问题。

from /Users/app/models/user.rb:61:in `block in <class:User>'
from /Users/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-deprecated_finders-1.0.3/lib/active_record/deprecated_finders/base.rb:28:in `call'
from /Users/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-deprecated_finders-1.0.3/lib/active_record/deprecated_finders/base.rb:28:in `call'
from /Users/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0.rc1/lib/active_record/scoping/named.rb:163:in `block (2 levels) in scope'
from /Users/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0.rc1/lib/active_record/relation.rb:246:in `scoping'
from /Users/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0.rc1/lib/active_record/scoping/named.rb:163:in `block in scope'
from /Users/app/models/user.rb:78:in `within_miles'
from (irb):2

user.rb:

scope :within_miles_of_zip, lambda {|radius, zip|
     # Get the parameters for the search
     area = zip.area_for(radius)

     # now find all zip codes that are within 
     # these min/max lat/lon bounds and return them
     # weed out any zip codes that fall outside of the search radius
     { :select => "#{User.columns.map{|c| "users.#{c.name}"}.join(', ')}, sqrt( 
         pow(#{area[:lat_miles]} * (zips.lat - #{zip.lat}),2) + 
         pow(#{area[:lon_miles]} * (zips.lon - #{zip.lon}),2)) as distance",
       :joins => :zip,
       :conditions => "(zips.lat BETWEEN #{area[:min_lat]} AND #{area[:max_lat]}) 
         AND (zips.lon BETWEEN #{area[:min_lon]} AND #{area[:max_lon]}) 
         AND sqrt(pow(#{area[:lat_miles]} * (zips.lat - #{zip.lat}),2) + 
         pow(#{area[:lon_miles]} * (zips.lon - #{zip.lon}),2)) <= #{area[:radius]}",
       :order => "distance"}
   }

   def within_miles(radius)
     self.class.within_miles_of_zip(radius, zip)
   end

zip.rb:

def area_for(radius)
    area = {}
    area[:radius] = radius.to_f
    area[:lat_miles] = 69.172  #this is constant

    #longitude miles varies based on latitude, that is calculated here
    area[:lon_miles] = (area[:lat_miles] * Math.cos(lat * (Math::PI/180))).abs

    area[:lat_degrees] = radius/area[:lat_miles]  #radius in degrees latitude
    area[:lon_degrees] = radius/area[:lon_miles]  #radius in degrees longitude

    #now set min and max lat and long accordingly
    area[:min_lat] = lat - area[:lat_degrees]
    area[:max_lat] = lat + area[:lat_degrees]
    area[:min_lon] = lon - area[:lon_degrees]
    area[:max_lon] = lon + area[:lon_degrees]    

    area  
  end

1 个答案:

答案 0 :(得分:0)

within_miles_of_zip范围期望将Zip对象传递给它。在within_miles类方法中传递一个:

def within_miles(radius)
    zip = Zip.find_by_zip('94109') # or whatever you do to look up a zip
    self.class.within_miles_of_zip(radius, zip)
end