thinking-sphinx has_many :through relationships
I've got a many-to-many relationship between ledger and staff and would like to use Thinking-Sphinx (TS) to search ledgers which the current_staff member owns.
In Rails 3 console I've tried the following
> Ledger.search 'test', :include => :staff_ids, :with => {:staff_ids => 1}
Returns []
> Ledger.search 'test', :include => :staff_id, :condition => {:staff_id => 1}
Returns ledgers which do not belong to staff member with id 1.
Ledger Model
class Ledger < ActiveRecord::Base
has_many :employees
has_many :staff, :through => :employees
define_index do
indexes :name
# indexes staff.id, :as => :staff_id # many to many relationship.
has staff(:id), :as => :staff_ids # many to many relationship.
set_property :delta => true
end
end
Staff Model
class Staff < ActiveRecord::Base
has_many :employees
has_many :ledgers, :throu开发者_如何学编程gh => :employees
define_index do
indexes username
indexes surname
indexes firstname
set_property :delta => true # http://freelancing-god.github.com/ts/en/deltas.html
end
end
I have got the following inflection setup
inflect.uncountable %w( staff )
I've tried indexes and has in my Ledger model, rebuilding and restarting TS after each change to indexes.
Update1:
I'm very close. If I do a 'rake ts:reindex' then restart me rails server, my search on ledgers (associated to the current_staff) works fine:
@results = Ledger.search params[:search], :include =>:staff_id, :conditions =>{:staff_id => current_staff.id}
It's almost like I have to have a delta on my has_many :through model, is this correct?
Update 2:
I've started to play around with Delta's and associations as in the thinking-sphinx documentation. Still doesn't seem to work though.
Here is what I've put in my Ledger model:
after_save :set_staff_delta_flag
...
private
def set_staff_delta_flag
staff.delta = true
staff.save
end
I get the following error when trying to add a new ledger:
NoMethodError (undefined method `delta=' for #<Class:0x00000001516340>):
app/models/ledger.rb:19:in `set_staff_delta_flag'
app/controllers/ledgers_controller.rb:24:in `create'
I found the answer!
I have to set the staff delta flag after the save, but as I have multiple I have to do that for each staff.
Here is my ledger model
class Ledger < ActiveRecord::Base
has_many :employees
has_many :staff, :through => :employees
after_save :set_staff_delta_flag
define_index do
indexes :name
indexes staff.id, :as => :staff_id # many to many relationship.
set_property :delta => true
end
private
def set_staff_delta_flag
staff.map{ |s| s.update_attribute("delta", true)}
end
end
Now in my Rails app if I add a new ledger for a current staff member and use the following I can see the new ledger in the search results.
@results = Ledger.search params[:search], :include =>:staff_id, :conditions =>{:staff_id => current_staff.id}
If there is a better way to do this let me know.
It resolved itself for me when I added attr_accessor :delta
to the models that I was delta indexing.
精彩评论