Skip to content
This repository was archived by the owner on Sep 27, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Fuzzily - fuzzy string matching for ActiveRecord

This version of fuzzily contains experimental extensions to the [original gem](https://github.com/mezis/fuzzily). Unless you seriously want some of the extensions - further described below - please use the original gem.

[![Gem Version](https://badge.fury.io/rb/fuzzily.png)](http://badge.fury.io/rb/fuzzily)
[![Build Status](https://travis-ci.org/mezis/fuzzily.png?branch=master)](https://travis-ci.org/mezis/fuzzily)
[![Dependency Status](https://gemnasium.com/mezis/fuzzily.png)](https://gemnasium.com/mezis/fuzzily)
Expand Down Expand Up @@ -166,6 +168,14 @@ class Employee < ActiveRecord::Base
end
```

## Extensions provided compared to the original gem

This version of fuzzily contains experimental extensions to the [original gem](https://github.com/mezis/fuzzily). Unless you seriously want some of the extensions - further described below - please use the original gem.

- Branch mass\_assignment: Avoid problems related to mass-assignment (this feature is now merged into the original gem)
- Branch apply\_on\_scope: same as mass\_assignment + makes it possible to apply find\_by\_fuzzy on a relation/scope, like for example:
Person.where('country = ?', "France").find_by_fuzzy_name(the_name, :limit => 20)



## License
Expand Down
36 changes: 31 additions & 5 deletions lib/fuzzily/searchable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ def self.included(by)
def _update_fuzzy!(_o)
self.send(_o.trigram_association).delete_all
String.new(self.send(_o.field)).scored_trigrams.each do |trigram, score|
self.send(_o.trigram_association).create!(:score => score, :trigram => trigram, :owner_type => self.class.name)
# The create! with parameters causes a Rails exception for mass assignment
# self.send(_o.trigram_association).create!(:score => score, :trigram => trigram, :owner_type => self.class.name)
cfo=self.send(_o.trigram_association).new
cfo.score = score
cfo.trigram = trigram
cfo.owner_type = self.class.name
cfo.save!
end
end

Expand All @@ -39,19 +45,39 @@ def _find_by_fuzzy(_o, pattern, options={})
options[:offset] ||= 0

trigrams = _o.trigram_class_name.constantize.
limit(options[:limit]).
# Christer 2a) Don't apply limit yet
# limit(options[:limit]).
offset(options[:offset]).
for_model(self.name).
for_field(_o.field.to_s).
matches_for(pattern)
records = _load_for_ids(trigrams.map(&:owner_id))
# Christer 2b) Send limit param along
# records = _load_for_ids(trigrams.map(&:owner_id))
records = _load_for_ids1(trigrams.map(&:owner_id), options[:limit])
# order records as per trigram query (no portable way to do this in SQL)
trigrams.map { |t| records[t.owner_id] }
trigrams.map { |t| records[t.owner_id] }.compact
end

def _load_for_ids(ids)
{}.tap do |result|
find(ids).each { |_r| result[_r.id] = _r }
# Christer 1): breaks if object with id is not found (eg. we're applying fuzzy search to scope)
# find(ids).each { |_r| result[_r.id] = _r }
# Replace with
ids.each{|id|
result[id] = find_by_id(id) if find_by_id(id).present?
}
end
end

# Christer 2c) Apply params[:limit] while creating the hash
def _load_for_ids1(ids, limit)
{}.tap do |result|
ids.each{|id|
if find_by_id(id).present?
result[id] = find_by_id(id)
break if ((limit-=1) == 0)
end
}
end
end

Expand Down