ruby on rails 3 - Trying to access sphinx internal data -
i have table countries (model listed below). adding thinking sphinx search , use results displayed.
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 indexes country_name, :sortable => true has created_at, updated_at has "(select count(provinces.id) provinces provinces.country_id = id)", :as => :province_count, :type => :integer end
in view need add conditional link provinces belong country if province count country greater 0.
count = country.provinces.count if count > 0 link_to(country.country_name, provinces_path(:id => country.id)) else country.country_name end
i tried replace active record query count with
count = country.search(:select => "province_count", :with => {:country_name => country.country_name})
but not yet successful in getting work yet. how can achieved. working off of this link
two things note should solve problem:
firstly, can force join on associations using join
method in index definition - saves on need full subquery:
thinkingsphinx::index.define :country, :with => :active_record indexes country_name, :sortable => true has created_at, updated_at has "count(provinces.id)", :as => :province_count, :type => :integer join provinces end
secondly, , more importantly, if wish access sphinx attributes when using search results, need use thinking sphinx pane purpose:
search = country.search(:with => {:sphinx_internal_id => country.id}) search.context[:panes] << thinkingsphinx::panes::attributespane count = search.first.sphinx_attributes['province_count']
you'll note i'm filtering primary key instead of country name - id more specific, end specific matches, , also, country name field, not attribute, if want filter fields, use :conditions
instead of :with
. , if was attribute, can't filter it, sphinx doesn't support filters on string attributes.
please note copying , pasting these 3 lines rails console not work, because console not evaluates lines, outputs result, , outputting search result invokes call sphinx - , panes don't applied appropriately. workaround include ; ''
@ end of first line, result gets output empty string:
search = country.search(:with => {:sphinx_internal_id => country.id}); '' search.context[:panes] << thinkingsphinx::panes::attributespane count = search.first.sphinx_attributes['province_count']
if performing broad search, not on specific country, , want provinces count each country, can stop reading here. remove filter, make sure add pane, , you're go.
but, if you're running on single country record....
you can simplify things further - want count, after all, not actual country object:
search = country.search( :with => {:sphinx_internal_id => country.id}, :middleware => thinkingsphinx::middlewares::raw_only ) search.first['province_count']
but really, if have country object, running search sole purpose of getting number of provinces feels overkill me. either call country.provinces.count
, or use activerecord's counter_cache
option , have column provinces_count
on country model - undoubtedly fastest option in long run.
(sorry, answer ended being far longer expected - covers off few different avenues.)
Comments
Post a Comment