Skip to content
This repository has been archived by the owner on Sep 27, 2022. It is now read-only.

Commit

Permalink
Merge e22e10d into 31a6880
Browse files Browse the repository at this point in the history
  • Loading branch information
mezis committed Aug 31, 2013
2 parents 31a6880 + e22e10d commit 61acba5
Show file tree
Hide file tree
Showing 19 changed files with 326 additions and 114 deletions.
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ gemfile:
- gemfiles/rails32.gemfile
- gemfiles/rails32_pg.gemfile
- gemfiles/rails32_mysql.gemfile
- gemfiles/rails40.gemfile
before_install: bundle install
bundler_args:
matrix:
exclude:
- rvm: 2.0.0
gemfile: gemfiles/rails23.gemfile
env: TRAVIS=TRUE
before_script:
- psql -c 'create database fuzzily_test;' -U postgres
- mysql -e 'create database fuzzily_test;'
env: TRAVIS=TRUE
env:
global:
- TRAVIS=TRUE
4 changes: 4 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ end
appraise "rails32-mysql" do
gem "activerecord", "~> 3.2.0"
end

appraise "rails40" do
gem "activerecord", "~> 4.0.0"
end
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
source ENV.fetch('GEM_SOURCE','https://rubygems.org')

gem "activerecord", "~> 3.2.1"

# Specify your gem's dependencies in fuzzily.gemspec
gemspec

33 changes: 17 additions & 16 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
PATH
remote: .
specs:
fuzzily (0.2.4)
fuzzily (0.3.0)
activerecord (>= 2.3.17)

GEM
remote: http://yarp.dev/
remote: https://rubygems.org/
specs:
activemodel (3.2.14)
activesupport (= 3.2.14)
Expand Down Expand Up @@ -33,12 +33,12 @@ GEM
thor
diff-lcs (1.2.4)
i18n (0.6.5)
method_source (0.8.1)
mime-types (1.23)
method_source (0.8.2)
mime-types (1.25)
multi_json (1.7.9)
mysql2 (0.3.11)
pg (0.15.1)
pry (0.9.12.1)
mysql2 (0.3.13)
pg (0.16.0)
pry (0.9.12.2)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
Expand All @@ -47,27 +47,28 @@ GEM
rake (10.1.0)
rest-client (1.6.7)
mime-types (>= 1.16)
rspec (2.13.0)
rspec-core (~> 2.13.0)
rspec-expectations (~> 2.13.0)
rspec-mocks (~> 2.13.0)
rspec-core (2.13.1)
rspec-expectations (2.13.0)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.5)
rspec-expectations (2.14.2)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.13.1)
rspec-mocks (2.14.3)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
simplecov-html (0.7.1)
slop (3.4.4)
sqlite3 (1.3.7)
slop (3.4.6)
sqlite3 (1.3.8)
thor (0.18.1)
tzinfo (0.3.37)

PLATFORMS
ruby

DEPENDENCIES
activerecord (~> 3.2.1)
appraisal
coveralls
fuzzily!
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Blurrily finds misspelled, prefix, or partial needles in a haystack of
strings. It's a fast, [trigram](http://en.wikipedia.org/wiki/N-gram)-based, database-backed [fuzzy](http://en.wikipedia.org/wiki/Approximate_string_matching) string search/match engine for Rails.
Loosely inspired from an [old blog post](http://unirec.blogspot.co.uk/2007/12/live-fuzzy-search-using-n-grams-in.html).

Tested with ActiveRecord (2.3, 3.0, 3.1, 3.2) on various Rubies (1.8.7, 1.9.2, 1.9.3, 2.0.0) and the most common adapters (SQLite3, MySQL, and PostgreSQL).
Tested with ActiveRecord (2.3, 3.0, 3.1, 3.2, 4.0) on various Rubies (1.8.7, 1.9.2, 1.9.3, 2.0.0) and the most common adapters (SQLite3, MySQL, and PostgreSQL).

If your dateset is big, if you need yet more speed, or do not use ActiveRecord,
check out [blurrily](http://github.com/mezis/blurrily), another gem (backed with a C extension)
Expand Down Expand Up @@ -71,7 +71,9 @@ Search!
MyStuff.find_by_fuzzy_name('Some Name', :limit => 10)
# => records

You can force an update on a specific record with

MyStuff.find(123).update_fuzzy_name!

## Indexing more than one field

Expand Down
6 changes: 3 additions & 3 deletions gemfiles/rails23.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: /Users/mezis/Dropbox/Development/fuzzily
specs:
fuzzily (0.2.4)
fuzzily (0.3.0)
activerecord (>= 2.3.17)

GEM
Expand Down Expand Up @@ -48,8 +48,8 @@ GEM
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
simplecov-html (0.7.1)
slop (3.4.4)
sqlite3 (1.3.7)
slop (3.4.6)
sqlite3 (1.3.8)
thor (0.18.1)

PLATFORMS
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails30.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: /Users/mezis/Dropbox/Development/fuzzily
specs:
fuzzily (0.2.4)
fuzzily (0.3.0)
activerecord (>= 2.3.17)

GEM
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails31.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: /Users/mezis/Dropbox/Development/fuzzily
specs:
fuzzily (0.2.4)
fuzzily (0.3.0)
activerecord (>= 2.3.17)

GEM
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails32.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: /Users/mezis/Dropbox/Development/fuzzily
specs:
fuzzily (0.2.4)
fuzzily (0.3.0)
activerecord (>= 2.3.17)

GEM
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails32_mysql.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: /Users/mezis/Dropbox/Development/fuzzily
specs:
fuzzily (0.2.4)
fuzzily (0.3.0)
activerecord (>= 2.3.17)

GEM
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails32_pg.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: /Users/mezis/Dropbox/Development/fuzzily
specs:
fuzzily (0.2.4)
fuzzily (0.3.0)
activerecord (>= 2.3.17)

GEM
Expand Down
7 changes: 7 additions & 0 deletions gemfiles/rails40.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 4.0.0"

gemspec :path=>"../"
89 changes: 89 additions & 0 deletions gemfiles/rails40.gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
PATH
remote: /Users/mezis/Dropbox/Development/fuzzily
specs:
fuzzily (0.3.0)
activerecord (>= 2.3.17)

GEM
remote: https://rubygems.org/
specs:
activemodel (4.0.0)
activesupport (= 4.0.0)
builder (~> 3.1.0)
activerecord (4.0.0)
activemodel (= 4.0.0)
activerecord-deprecated_finders (~> 1.0.2)
activesupport (= 4.0.0)
arel (~> 4.0.0)
activerecord-deprecated_finders (1.0.3)
activesupport (4.0.0)
i18n (~> 0.6, >= 0.6.4)
minitest (~> 4.2)
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
appraisal (0.5.2)
bundler
rake
arel (4.0.0)
atomic (1.1.13)
builder (3.1.4)
coderay (1.0.9)
colorize (0.5.8)
coveralls (0.6.7)
colorize
multi_json (~> 1.3)
rest-client
simplecov (>= 0.7)
thor
diff-lcs (1.2.4)
i18n (0.6.5)
method_source (0.8.2)
mime-types (1.25)
minitest (4.7.5)
multi_json (1.7.9)
mysql2 (0.3.13)
pg (0.16.0)
pry (0.9.12.2)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
pry-nav (0.2.3)
pry (~> 0.9.10)
rake (10.1.0)
rest-client (1.6.7)
mime-types (>= 1.16)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.5)
rspec-expectations (2.14.2)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.14.3)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
simplecov-html (0.7.1)
slop (3.4.6)
sqlite3 (1.3.8)
thor (0.18.1)
thread_safe (0.1.2)
atomic
tzinfo (0.3.37)

PLATFORMS
ruby

DEPENDENCIES
activerecord (~> 4.0.0)
appraisal
coveralls
fuzzily!
mysql2
pg
pry
pry-nav
rake
rspec
sqlite3
2 changes: 1 addition & 1 deletion lib/fuzzily.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
require "fuzzily/model"
require "active_record"

ActiveRecord::Base.extend(Fuzzily::Searchable)
ActiveRecord::Base.send :include, Fuzzily::Searchable
75 changes: 54 additions & 21 deletions lib/fuzzily/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ module Model

def self.included(by)
by.ancestors.include?(ActiveRecord::Base) or raise 'Not included in an ActiveRecord subclass'

scope_method = ActiveRecord::VERSION::MAJOR == 2 ? :named_scope : :scope
by.extend(ClassMethods)

by.class_eval do
return if class_variable_defined?(:@@fuzzily_trigram_model)
Expand All @@ -18,31 +17,65 @@ def self.included(by)
validates_presence_of :score
validates_presence_of :fuzzy_field

send scope_method, :for_model, lambda { |model| {
:conditions => { :owner_type => model.kind_of?(Class) ? model.name : model }
}}
send scope_method, :for_field, lambda { |field_name| {
:conditions => { :fuzzy_field => field_name }
}}
send scope_method, :with_trigram, lambda { |trigrams| {
:conditions => { :trigram => trigrams }
}}

_add_fuzzy_scopes
class_variable_set(:@@fuzzily_trigram_model, true)
end

by.extend(ClassMethods)
end

module ClassMethods
def matches_for(text)
trigrams = Fuzzily::String.new(text).trigrams
self.
scoped(:select => 'owner_id, owner_type, count(*) AS matches, MAX(score) AS score').
scoped(:group => 'owner_id, owner_type').
scoped(:order => 'matches DESC, score ASC').
with_trigram(trigrams).
map(&:owner)
_matches_for_trigrams Fuzzily::String.new(text).trigrams
end

private

module Rails2
def _matches_for_trigrams(trigrams)
self.
scoped(:select => 'owner_id, owner_type, count(*) AS matches, MAX(score) AS score').
scoped(:group => 'owner_id, owner_type').
scoped(:order => 'matches DESC, score ASC').
with_trigram(trigrams).
map(&:owner)
end

def _add_fuzzy_scopes
named_scope :for_model, lambda { |model| {
:conditions => { :owner_type => model.kind_of?(Class) ? model.name : model }
}}
named_scope :for_field, lambda { |field_name| {
:conditions => { :fuzzy_field => field_name }
}}
named_scope :with_trigram, lambda { |trigrams| {
:conditions => { :trigram => trigrams }
}}
named_scope :limit, lambda { |count| { :limit => count }}
end
end

module Rails3
def _matches_for_trigrams(trigrams)
self.
select('owner_id, owner_type, count(*) AS matches, MAX(score) AS score').
group('owner_id, owner_type').
order('matches DESC, score ASC').
with_trigram(trigrams).
map(&:owner)
end

def _add_fuzzy_scopes
scope :for_model, lambda { |model|
where(:owner_type => model.kind_of?(Class) ? model.name : model)
}
scope :for_field, lambda { |field_name| where(:fuzzy_field => field_name) }
scope :with_trigram, lambda { |trigrams| where(:trigram => trigrams) }
end
end

if ActiveRecord::VERSION::MAJOR == 2
include Rails2
else
include Rails3
end
end
end
Expand Down

0 comments on commit 61acba5

Please sign in to comment.