我通过以下rake任务得到了undefined local variable or method 'address_geo' for main:Object
。这有什么问题?
include Geokit::Geocoders
namespace :geocode do
desc "Geocode to get latitude, longitude and address"
task :all => :environment do
@spot = Spot.find(:first)
if @spot.latitude.blank? && !@spot.address.blank?
puts address_geo
end
def address_geo
arr = []
arr << address if @spot.address
arr << city if @spot.city
arr << country if @spot.country
arr.reject{|y|y==""}.join(", ")
end
end
end
答案 0 :(得分:97)
您正在rake任务中定义方法。要获得该功能,您应该在rake任务之外定义(在任务块之外)。试试这个:
include Geokit::Geocoders
namespace :geocode do
desc "Geocode to get latitude, longitude and address"
task :all => :environment do
@spot = Spot.find(:first)
if @spot.latitude.blank? && !@spot.address.blank?
puts address_geo
end
end
def address_geo
arr = []
arr << address if @spot.address
arr << city if @spot.city
arr << country if @spot.country
arr.reject{|y|y==""}.join(", ")
end
end
答案 1 :(得分:21)
我建议将方法提取到模块或类中。这是因为rake文件中定义的方法最终在全局命名空间中定义。即,然后可以从任何地方调用它们,而不仅仅是在该rake文件中(即使它是命名空间!)。
这也意味着如果在两个不同的rake任务中有两个具有相同名称的方法,其中一个将在您不知情的情况下被覆盖。非常致命。
这里有一个很好的解释:https://kevinjalbert.com/defined_methods-in-rake-tasks-you-re-gonna-have-a-bad-time/
答案 2 :(得分:0)
您可以使用Proc
来获得相同的效果,而无需使用全局方法声明。例如,
include Geokit::Geocoders
namespace :geocode do
desc "Geocode to get latitude, longitude and address"
task :all => :environment do
address_geo = Proc.new do
arr = []
arr << address if @spot.address
arr << city if @spot.city
arr << country if @spot.country
arr.reject{|y|y==""}.join(", ")
end
@spot = Spot.find(:first)
if @spot.latitude.blank? && !@spot.address.blank?
puts address_geo.call
end
end
end