Skip to content

Commit

Permalink
Shifting initialisation of results into collection, and adding each_w…
Browse files Browse the repository at this point in the history
…ith_* methods
  • Loading branch information
pat committed Sep 3, 2008
1 parent 3b5bc27 commit 9d32adc
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 8 deletions.
67 changes: 67 additions & 0 deletions lib/thinking_sphinx/collection.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,56 @@
module ThinkingSphinx
class Collection < ::Array
attr_reader :total_entries, :total_pages, :current_page
attr_accessor :results

def initialize(page, per_page, entries, total_entries)
@current_page, @per_page, @total_entries = page, per_page, total_entries

@total_pages = (entries / @per_page.to_f).ceil
end

def self.create_from_results(results, page, limit, options)
collection = self.new(page, limit,
results[:total] || 0, results[:total_found] || 0
)
collection.results = results
collection.replace instances_from_matches(results[:matches], options)
return collection
end

def self.instances_from_matches(matches, options = {})
return matches.collect { |match|
instance_from_match match, options
} unless klass = options[:class]

ids = matches.collect { |match| match[:attributes]["sphinx_internal_id"] }
instances = ids.length > 0 ? klass.find(
:all,
:conditions => {klass.primary_key.to_sym => ids},
:include => options[:include],
:select => options[:select]
) : []
ids.collect { |obj_id|
instances.detect { |obj| obj.id == obj_id }
}
end

def self.instance_from_match(match, options)
class_from_crc(match[:attributes]["class_crc"]).find(
match[:attributes]["sphinx_internal_id"],
:include => options[:include],
:select => options[:select]
)
end

def self.class_from_crc(crc)
@@models_by_crc ||= ThinkingSphinx.indexed_models.inject({}) do |hash, model|
hash[model.constantize.to_crc32] = model
hash
end
@@models_by_crc[crc].constantize
end

def previous_page
current_page > 1 ? (current_page - 1) : nil
end
Expand All @@ -19,5 +62,29 @@ def next_page
def offset
(current_page - 1) * @per_page
end

def method_missing(method, *args, &block)
super unless method.to_s[/^each_with_.*/]

each_with_attribute method.to_s.gsub(/^each_with_/, ''), &block
end

def each_with_group_and_count(&block)
results[:matches].each_with_index do |match, index|
yield self[index], match[:attributes]["@group"], match[:attributes]["@count"]
end
end

def each_with_attribute(attribute, &block)
results[:matches].each_with_index do |match, index|
yield self[index], (match[:attributes][attribute] || match[:attributes]["@#{attribute}"])
end
end

def each_with_weighting(&block)
results[:matches].each_with_index do |match, index|
yield self[index], match[:weight]
end
end
end
end
9 changes: 5 additions & 4 deletions lib/thinking_sphinx/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,11 @@ def search(*args)
page = options[:page] ? options[:page].to_i : 1

# begin
pager = ThinkingSphinx::Collection.new(page, client.limit,
results[:total] || 0, results[:total_found] || 0)
pager.replace instances_from_results(results[:matches], options, klass)
pager
# pager = ThinkingSphinx::Collection.new(page, client.limit,
# results[:total] || 0, results[:total_found] || 0)
# pager.replace instances_from_results(results[:matches], options, klass)
# pager
ThinkingSphinx::Collection.create_from_results(results, page, client.limit, options)
# pager = WillPaginate::Collection.create(page,
# client.limit, results[:total] || 0) do |collection|
# collection.replace instances_from_results(results[:matches], options, klass)
Expand Down
6 changes: 3 additions & 3 deletions spec/fixtures/models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ class Person < ActiveRecord::Base
indexes team.name, :as => :team_name
indexes contacts.phone_number, :as => :phone_numbers

has [first_name, middle_initial, last_name], :as => :name
has team.name, :as => :team_name
has [first_name, middle_initial, last_name], :as => :name_sort
has team.name, :as => :team_name_sort

has [:id, :team_id], :as => :ids
has team(:id), :as => :team_id

has contacts.phone_number, :as => :phone_numbers
has contacts.phone_number, :as => :phone_number_sort
has contacts(:id), :as => :contact_ids

has birthday
Expand Down
40 changes: 40 additions & 0 deletions spec/unit/thinking_sphinx/collection_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'spec/spec_helper'

describe ThinkingSphinx::Collection do
it "should return items paired to their attribute values" do
results = Person.search ""
results.should_not be_empty
results.each_with_sphinx_internal_id do |result, id|
result.id.should == id
end
end

it "should return items paired with their weighting" do
results = Person.search "Ellie Ford", :match_mode => :any
results.should_not be_empty
results.each_with_weighting do |result, weight|
result.should be_kind_of(Person)
weight.should be_kind_of(Integer)
end
end

it "should return items paired with their count if grouping" do
results = Person.search :group_function => :attr, :group_by => "birthday"
results.should_not be_empty
results.each_with_count do |result, count|
result.should be_kind_of(Person)
count.should be_kind_of(Integer)
end
end

it "should return items paired with their count and group value" do
results = Person.search :group_function => :attr, :group_by => "birthday"
results.should_not be_empty
results.each_with_group_and_count do |result, group, count|
result.should be_kind_of(Person)
# sometimes the grouping value will be nil/null
group.should be_kind_of(Integer) unless group.nil?
count.should be_kind_of(Integer)
end
end
end
2 changes: 1 addition & 1 deletion spec/unit/thinking_sphinx/index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@

describe "empty? method" do
before :each do
@index = ThinkingSphinx::Index.new(Person)
@index = ThinkingSphinx::Index.new(Contact)
config = ThinkingSphinx::Configuration.new

`mkdir -p #{config.searchd_file_path}`
Expand Down

0 comments on commit 9d32adc

Please sign in to comment.