我在我的应用程序中使用Geocoder和Sunspot gem,我有一个名为:search_near_address
的字段,可以让用户输入他们想要搜索的地址在X amount of miles
附近。我要映射的是我的商店:address
,用于:search_near_address
字段。这样,用户可以在:search_near_address
字段中输入地址(即451 University Avenue,Palo Alto,CA),它将在半径50英里内搜索。
太阳黑子1.2.1
class Store < ActiveRecord::Base
attr_accessible :address, :latitude, :longitude
has_many :products
geocoded_by :address
after_validation :geocode
reverse_geocoded_by :latitude, :longitude
after_validation :reverse_geocode
end
class Product < ActiveRecord::Base
belongs_to :store
searchable do # Searching with product model.
string :search_near # For rake sunspot:reindex
location :location
end
def search_near_address
store.address if store # You may have to use the "if store".
end
def location
# may need the "if store" after longitude)....
Sunspot::Util::Coordinates.new(store.latitude, store.longitude)
end
end
class SearchController < ApplicationController
def index
@search = Product.search do |q| # Search with sunspot
q.fulltext params[:search]
q.with(:location).near(*Geocoder.coordinates(params[:search_near_address]), :precision => 4) if params[:search_near_address].present?
end
@products = @search.results # Return results from Product.search block.
end
end
# search/index/html.erb
<%= form_tag results_search_index_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search] %>
<%= text_field_tag :search_near_address, params[:search_near_address] %>
<%= submit_tag "Go", :name => nil %>
<% end %>
答案 0 :(得分:7)
首先,@ m_x说的是对的,你不能指望将@#附近的商店#分配到@search对象会起作用....
只需阅读https://github.com/sunspot/sunspot中有关地理空间的文档,您就可以清楚地看到您遗漏了一些内容:
您必须使用地理编码器所需的纬度和经度字段声明您的地理空间字段:
class Product < ActiveRecord::Base
belongs_to :store
searchable do # for Sunspot search.
string :search_near
latlon(:location) {
Sunspot::Util::Coordinates.new(category.latitude, category.longitude)
}
end
def search_near
#I changed this because business_store will not work out.
store.address
end
end
然后你可以搜索(在索引之后)像这样:
class SearchController < ApplicationController
def index
# Search with sunspot
@search = Sunspot.search(Product) do
fulltext params[:search]
# The "*" pop off the elements of the array that
# Geocoder.coordinates returns.
with(:location).near(*Geocoder.coordinates(params[:search_near]),
:precision => 6)
# NOTE: You could also use the in_radius method but only in the pre-release version:
# with(:location).in_radius(*Geocoder.coordinates(params[:search_near]), 100) if params[:search_near].present?
end
# Return results from Product.search block.
@products = @search.results
end
end
另请阅读此处的{precision选项http://sunspot.github.com/docs/Sunspot/DSL/RestrictionWithNear.html#near-instance_method
关于Geocoder https://github.com/alexreisner/geocoder
答案 1 :(得分:3)
我不确定我是否完全理解您尝试使用上述内容的方法,但我在试图让地理编码器和太阳黑子一起玩时也有类似的情况。
这尚未经过测试,但这是我目前的想法......
Event.search do
keywords search_terms
any_of do
with(:id).any_of(Event.near(coordinates,50).map(&:id))
end
end.results
基本上我正在尝试将两个结果集合并为仅返回与距离和关键字术语匹配的结果。
希望这至少对某人有帮助。