diff --git a/Gemfile.lock b/Gemfile.lock index 6a3b5a2..74fc37e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,21 +7,21 @@ PATH GEM remote: https://rubygems.org/ specs: - activemodel (3.2.14) - activesupport (= 3.2.14) + activemodel (3.2.22.1) + activesupport (= 3.2.22.1) builder (~> 3.0.0) - activerecord (3.2.14) - activemodel (= 3.2.14) - activesupport (= 3.2.14) + activerecord (3.2.22.1) + activemodel (= 3.2.22.1) + activesupport (= 3.2.22.1) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activesupport (3.2.14) + activesupport (3.2.22.1) i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) appraisal (0.5.2) bundler rake - arel (3.0.2) + arel (3.0.3) builder (3.0.4) coderay (1.0.9) colorize (0.5.8) @@ -32,10 +32,10 @@ GEM simplecov (>= 0.7) thor diff-lcs (1.2.4) - i18n (0.6.5) + i18n (0.7.0) method_source (0.8.2) mime-types (1.25) - multi_json (1.7.9) + multi_json (1.11.2) mysql2 (0.3.13) pg (0.16.0) pry (0.9.12.2) @@ -62,7 +62,7 @@ GEM slop (3.4.6) sqlite3 (1.3.8) thor (0.18.1) - tzinfo (0.3.37) + tzinfo (0.3.46) PLATFORMS ruby diff --git a/lib/fuzzily/searchable.rb b/lib/fuzzily/searchable.rb index f8f4ab7..4207e1e 100644 --- a/lib/fuzzily/searchable.rb +++ b/lib/fuzzily/searchable.rb @@ -18,6 +18,9 @@ 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).build.tap do |record| + # I ran into problems where owner wasn't being set for some reason. + # I wasn't able to reproduce it in tests though :/ + record.owner = self record.score = score record.trigram = trigram record.fuzzy_field = _o.field.to_s @@ -136,7 +139,7 @@ def make_field_fuzzily_searchable(field, options={}) after_save do |record| next unless record.send("#{field}_changed?".to_sym) - + record.send(_o.update_trigrams_method) end diff --git a/spec/fuzzily/searchable_spec.rb b/spec/fuzzily/searchable_spec.rb index 9c25fe0..86daefe 100644 --- a/spec/fuzzily/searchable_spec.rb +++ b/spec/fuzzily/searchable_spec.rb @@ -12,9 +12,17 @@ before(:each) { prepare_trigrams_table } before(:each) { prepare_owners_table } - subject do + subject do silence_warnings do - Stuff = Class.new(ActiveRecord::Base) + Stuff = Class.new(ActiveRecord::Base) do + def full_name + "#{first_name} #{last_name}" + end + + def full_name_changed? + first_name_changed? || last_name_changed? + end + end end def Stuff.name ; 'Stuff' ; end Stuff @@ -43,29 +51,58 @@ def Stuff.name ; 'Stuff' ; end end describe '(callbacks)' do - before { subject.fuzzily_searchable :name } + context "with a database backed column" do + before { subject.fuzzily_searchable :name } - it 'generates trigram records on creation' do - subject.create!(:name => 'Paris') - subject.last.trigrams_for_name.should_not be_empty - end + it 'generates trigram records on creation' do + subject.create!(:name => 'Paris') + subject.last.trigrams_for_name.should_not be_empty + end - it 'generates the correct trigrams' do - record = subject.create!(:name => 'FOO') - Trigram.first.trigram.should == '**f' - Trigram.first.owner_id.should == record.id - Trigram.first.owner_type.should == 'Stuff' - end + it 'generates the correct trigrams' do + record = subject.create!(:name => 'FOO') + Trigram.first.trigram.should == '**f' + Trigram.first.owner_id.should == record.id + Trigram.first.owner_type.should == 'Stuff' + end - it 'updates all trigram records on save' do - subject.create!(:name => 'Paris') - subject.first.update_attribute :name, 'Rome' - Trigram.all.map(&:trigram).should =~ %w(**r *ro rom ome me*) + it 'updates all trigram records on save' do + subject.create!(:name => 'Paris') + subject.first.update_attribute :name, 'Rome' + Trigram.all.map(&:trigram).should =~ %w(**r *ro rom ome me*) + end + + it 'deletes all trigrams on destroy' do + subject.create!(:name => 'Paris').destroy + Trigram.all.should be_empty + end end - it 'deletes all trigrams on destroy' do - subject.create!(:name => 'Paris').destroy - Trigram.all.should be_empty + context "with a virtual attribute" do + before { subject.fuzzily_searchable :full_name } + + it 'generates trigram records on creation' do + subject.create!(:first_name => 'Joe', :last_name => 'Bloggs') + subject.last.trigrams_for_full_name.should_not be_empty + end + + it 'generates the correct trigrams' do + record = subject.create!(:first_name => 'Joe', :last_name => 'Bloggs') + Trigram.first.trigram.should == '**j' + Trigram.first.owner_id.should == record.id + Trigram.first.owner_type.should == 'Stuff' + end + + it 'updates all trigram records on save' do + subject.create!(:first_name => 'Joe', :last_name => 'Bloggs') + subject.first.update_attribute :first_name, 'Sally' + Trigram.all.map(&:trigram).should =~ ["**s", "*bl", "*sa", "all", "blo", "ggs", "gs*", "lly", "log", "ly*", "ogg", "sal", "y*b"] + end + + it 'deletes all trigrams on destroy' do + subject.create!(:first_name => 'Joe', :last_name => 'Bloggs').destroy + Trigram.all.should be_empty + end end end @@ -73,7 +110,7 @@ def Stuff.name ; 'Stuff' ; end before do subject.fuzzily_searchable :name end - + it 're-creates trigrams' do subject.create!(:name => 'Paris') old_ids = Trigram.all.map(&:id) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 601a094..09b52c9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -43,6 +43,8 @@ class StuffMigration < ActiveRecord::Migration def self.up create_table :stuffs do |t| t.string :name + t.string :first_name + t.string :last_name t.string :data t.timestamps end