Rails:如何使用位置搜索向pg_search添加范围?

hel*_*llo 5 ruby scope ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2

我有两个型号,Location并且Basic,我使用pg_search地理编码宝石,如何添加范围,我pg_search_scope地理编码 near方法或是否有其他方法来做到这一点?

Location model具有纬度和经度列.

在我的控制器中,我能够做到这一点:

# this allows me to search near the Location model
@business = Location.near(params[:loc], 15)

# this searches through the pg_search_scope
@term = Basic.search(params[:q])

#I'm trying to combine @business and @term
Run Code Online (Sandbox Code Playgroud)

Basic模型我有这个:

pg_search_scope :search, :against => [:first_name, :last_name], 
  :associated_against => {
    :services => [:service, :description]
  },
  :using => {
    :tsearch => {:disctionary => "english" }
  }
Run Code Online (Sandbox Code Playgroud)

我想这两个结合起来@business,并@term成一个(@search)这可能吗?

谢谢

++++++++++++++++

所以在我的Basic模型中:

class Basic < ActiveRecord::Base
  belongs_to :location

  has_many :services, as: :servicable

  pg_search_scope :search, :against => [:first_name, :last_name], 
    :associated_against => {
      :services => [:service, :description]
    },
    :using => {
      :tsearch => {:disctionary => "english" }
    }

end
Run Code Online (Sandbox Code Playgroud)

所以在我的模型中,我有与基本链接的服务.所以当我搜索名称或服务结果弹出时.但我试图只显示用户输入的某个位置附近的结果,这就是为什么location_id我的Basic表中有一列.

这是我的Location模特

class Location < ActiveRecord::Base
  has_many :basics
  geocoded_by :new_address
  after_validation :geocode, :if => :new_address_changed?
  def gmaps4rails_address
    :new_address
  end
  def new_address_changed?
    attrs = %w(street city state)
    attrs.any?{|a| send "#{a}_changed?"}
  end  
end
Run Code Online (Sandbox Code Playgroud)

所以我试图链接这些方法.理想情况下,应用程序首先搜索所有附近的结果,然后搜索附近结果中匹配的术语,然后仅显示适用的结果.

小智 0

听起来您想要的是与术语匹配的Locations 附近params[:loc]并与之相关的s 。如果这种解释是错误的,那么其余的一切都将是错误的。Basicparams[:q]

要纯粹在数据库中执行此操作,您需要locations使用范围添加的条件将表near与使用添加的条件的表连接起来。不幸的是,我还没有找到任何方法来与其他表进行任意连接,所以我不知道对此有一个简单的基于查询的解决方案。但如果你的和结果相对较小,你可以直接在 ruby​​ 中进行连接。在您的控制器代码之后:basicsservicespg_search_scopepg_search_scope@business@term

@matching_businesses = @business & @term.map(&:location)
Run Code Online (Sandbox Code Playgroud)

还有其他方法可以做到这一点,但其想法是在结果Location中的那些和与结果中的 s@business相关的那些之间找到唯一的 s 集。这是另一种可能读起来更清楚的方式:Basic@term

@matching_businesses = @business.select do |business|
  @term.any? { |basic| business.basics.include?(basic) }
end
Run Code Online (Sandbox Code Playgroud)

如果这还不够性能,您可能需要编写自己的查询或通读实现pg_search_scope以找出如何使其支持任意连接。