我有一张国家桌子(下面列出的型号)。我正在添加思维狮身人面像作为搜索,并希望用它来显示结果。
country.rb
class Country < ActiveRecord::Base
has_many :provinces
has_many :cities
has_many :zones
has_many :users
attr_accessible :alpha_2, :alpha_3, :country_name, :numeric, :country_active
scope :ordered, order("country_name")
scope :active, where(:country_active => true)
end
country_index.rb
ThinkingSphinx::Index.define :country, :with => :active_record do
indexes country_name, :sortable => true
has created_at, updated_at
has "(select COUNT(provinces.id) from provinces where provinces.country_id = id)", :as => :province_count, :type => :integer
end
在我看来,如果该国的省份数大于0,我需要向属于某个国家的省份添加条件链接。
count = country.provinces.count
if count > 0
link_to(country.country_name, provinces_path(:id => country.id))
else
country.country_name
end
我尝试用
替换计数的活动记录查询count = Country.search(:select => "province_count", :with => {:country_name => country.country_name})
但尚未成功实现此功能。如何实现这一目标。我正在处理this link
答案 0 :(得分:1)
需要注意的两件事应该有助于解决这个问题:
首先,您可以通过在索引定义中使用join
方法强制关联联接 - 这样可以节省对完整子查询的需求:
ThinkingSphinx::Index.define :country, :with => :active_record do
indexes country_name, :sortable => true
has created_at, updated_at
has "COUNT(provinces.id)", :as => :province_count, :type => :integer
join provinces
end
其次,更重要的是,如果您希望在使用搜索结果时访问Sphinx属性,则需要使用Thinking Sphinx窗格来实现此目的:
search = Country.search(:with => {:sphinx_internal_id => country.id})
search.context[:panes] << ThinkingSphinx::Panes::AttributesPane
count = search.first.sphinx_attributes['province_count']
您会注意到我使用主键而不是国家/地区名称进行过滤 - ID更具体,因此您最终会获得特定匹配项,而且国家/地区名称是字段,而不是属性,因此,要按字段过滤,请使用:conditions
代替:with
。如果是属性,则无法按其进行过滤,因为Sphinx不支持字符串属性的过滤器。
请注意,将这三行复制并粘贴到Rails控制台中将不起作用,因为控制台不仅评估行,而且输出结果,并输出搜索结果调用Sphinx调用 - 因此窗格不会适当应用。解决方法是在第一行的末尾包含; ''
,因此获得输出的结果是空字符串:
search = Country.search(:with => {:sphinx_internal_id => country.id}); ''
search.context[:panes] << ThinkingSphinx::Panes::AttributesPane
count = search.first.sphinx_attributes['province_count']
如果您实际上正在进行广泛搜索,而不仅仅是针对特定国家/地区,并且您希望每个国家/地区都计入省份,则可以在此处停止阅读。删除过滤器,但请确保添加窗格,然后就可以了。
但是,如果你真的只在一个国家/地区的记录中运行它......
您可以进一步简化事情 - 毕竟,您只想要计数,而不是实际的Country对象:
search = Country.search(
:with => {:sphinx_internal_id => country.id},
:middleware => ThinkingSphinx::Middlewares::RAW_ONLY
)
search.first['province_count']
但是真的,如果你已经拥有了国家/地区对象,那么为了获得省份数量而进行搜索只会让我觉得有点过分。您只需拨打country.provinces.count
,或使用ActiveRecord的counter_cache
选项,然后在您的国家/地区型号上添加provinces_count
列 - 从长远来看,毫无疑问这是最快的选择。
(对不起,这个答案的结果比我预期的要长得多 - 但它涵盖了几个不同的途径。)