From 1e64d17a86157a0414219bffb8c5e88210422fb9 Mon Sep 17 00:00:00 2001 From: chrilleferna Date: Fri, 24 Jan 2014 14:40:21 +0100 Subject: [PATCH 1/7] Update searchable.rb Updates of fuzzily searchable objects cause Rails exceptions due to mass assignment of attributes from fuzzily --- lib/fuzzily/searchable.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/fuzzily/searchable.rb b/lib/fuzzily/searchable.rb index 5a310d0..4575adc 100644 --- a/lib/fuzzily/searchable.rb +++ b/lib/fuzzily/searchable.rb @@ -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 = owner_type + cfo.save! end end From e0085737ee50fbf3d6e251cb76b91072c7209578 Mon Sep 17 00:00:00 2001 From: chrilleferna Date: Sat, 25 Jan 2014 19:25:17 +0100 Subject: [PATCH 2/7] Update searchable.rb --- lib/fuzzily/searchable.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fuzzily/searchable.rb b/lib/fuzzily/searchable.rb index 4575adc..8b9365d 100644 --- a/lib/fuzzily/searchable.rb +++ b/lib/fuzzily/searchable.rb @@ -22,7 +22,7 @@ def _update_fuzzy!(_o) cfo=self.send(_o.trigram_association).new cfo.score = score cfo.trigram = trigram - cfo.owner_type = owner_type + cfo.owner_type = self.class.name cfo.save! end end From 90282ff20193bf02502389e02c1fd8d9703c7c25 Mon Sep 17 00:00:00 2001 From: chrilleferna Date: Mon, 27 Jan 2014 12:40:58 +0100 Subject: [PATCH 3/7] Update searchable.rb Fix 1: don't crash if applied to scope (but limit won't be accurate) Fix 2: take into account limit parameter --- lib/fuzzily/searchable.rb | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/fuzzily/searchable.rb b/lib/fuzzily/searchable.rb index 8b9365d..d5dcb50 100644 --- a/lib/fuzzily/searchable.rb +++ b/lib/fuzzily/searchable.rb @@ -45,19 +45,38 @@ def _find_by_fuzzy(_o, pattern, options={}) options[:offset] ||= 0 trigrams = _o.trigram_class_name.constantize. - limit(options[:limit]). + # Christer 2) 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 3) 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 + + 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 From 9f493e91efb668f2d592c0b50d2dca68c4f79337 Mon Sep 17 00:00:00 2001 From: chrilleferna Date: Mon, 27 Jan 2014 14:15:05 +0100 Subject: [PATCH 4/7] Update searchable.rb --- lib/fuzzily/searchable.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/fuzzily/searchable.rb b/lib/fuzzily/searchable.rb index d5dcb50..855c7ab 100644 --- a/lib/fuzzily/searchable.rb +++ b/lib/fuzzily/searchable.rb @@ -45,13 +45,13 @@ def _find_by_fuzzy(_o, pattern, options={}) options[:offset] ||= 0 trigrams = _o.trigram_class_name.constantize. - # Christer 2) Don't apply limit yet + # 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) - # Christer 3) Send limit param along + # 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) @@ -69,6 +69,7 @@ def _load_for_ids(ids) end end + # Christer 2c) Apply params[:limit] while creating the hash def _load_for_ids1(ids, limit) {}.tap do |result| ids.each{|id| From f0fcf123f65777bf89f1eda5be2558ede3ad1944 Mon Sep 17 00:00:00 2001 From: Christer Fernstrom Date: Fri, 7 Feb 2014 18:26:48 +0100 Subject: [PATCH 5/7] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 76e6b82..5e8898d 100644 --- a/README.md +++ b/README.md @@ -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) @@ -166,6 +168,11 @@ class Employee < ActiveRecord::Base end ``` +## Extensions provided compared to the original gem + +- Branch master: Avoid problems related to mass-assignment (this feature is now merged into the original gem) +- Branch apply_on_scope: 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 From c587028304f7baf9acce708e87dff24c3344b61a Mon Sep 17 00:00:00 2001 From: Christer Fernstrom Date: Fri, 7 Feb 2014 18:28:16 +0100 Subject: [PATCH 6/7] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e8898d..fa84275 100644 --- a/README.md +++ b/README.md @@ -170,8 +170,11 @@ 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 master: Avoid problems related to mass-assignment (this feature is now merged into the original gem) -- Branch apply_on_scope: 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) +- Branch apply_on_scope: 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) From 54739cf6e8ce7fc9528f2d4ac3d204279cfde2b5 Mon Sep 17 00:00:00 2001 From: Christer Fernstrom Date: Fri, 7 Feb 2014 19:03:34 +0100 Subject: [PATCH 7/7] Updated README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fa84275..1c364b1 100644 --- a/README.md +++ b/README.md @@ -172,8 +172,8 @@ end 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 master: Avoid problems related to mass-assignment (this feature is now merged into the original gem) -- Branch apply_on_scope: makes it possible to apply find_by_fuzzy on a relation/scope, like for example: +- 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)