lib/fuzzily/searchable.rb in fuzzily-0.0.1 vs lib/fuzzily/searchable.rb in fuzzily-0.0.2
- old
+ new
@@ -22,24 +22,53 @@
has_many trigram_association,
:class_name => trigram_class_name,
:as => :owner,
:conditions => { :fuzzy_field => field.to_s },
- :dependent => :destroy
+ :dependent => :destroy,
+ :autosave => true
singleton_class.send(:define_method,"find_by_fuzzy_#{field}".to_sym) do |*args|
case args.size
when 1 then pattern = args.first ; options = {}
when 2 then pattern, options = args
else raise 'Wrong # of arguments'
end
- Trigram.scoped(options).for_model(self.name).for_field(field).matches(pattern)
+
+ trigram_class_name.constantize.
+ scoped(options).
+ for_model(self.name).
+ for_field(field.to_s).
+ matches_for(pattern)
end
+ singleton_class.send(:define_method,"bulk_update_fuzzy_#{field}".to_sym) do
+ trigram_class = trigram_class_name.constantize
+
+ self.scoped(:include => trigram_association).find_in_batches(:batch_size => 100) do |batch|
+ inserts = []
+ batch.each do |record|
+ record.send(field).extend(String).trigrams.each do |trigram|
+ inserts << sanitize_sql_array(['(?,?,?,?,?)', self.name, record.id, field.to_s, 1, trigram])
+ end
+ end
+
+ trigram_class.transaction do
+ batch.each { |record| record.send(trigram_association).delete_all }
+ trigram_class.connection.insert(%Q{
+ INSERT INTO `#{trigram_class.table_name}`
+ (`owner_type`, `owner_id`, `fuzzy_field`, `score`, `trigram`)
+ VALUES
+ #{inserts.join(", ")}
+ })
+ end
+ end
+ end
+
define_method update_trigrams_method do
- self.send(trigram_association).destroy_all
+ self.send(trigram_association).delete_all
self.send(field).extend(String).trigrams.each do |trigram|
- self.send(trigram_association).create!(:score => 1, :trigram => trigram)
+ self.send(trigram_association).create!(:score => 1, :trigram => trigram, :owner_type => self.class.name)
end
end
after_save do |record|
next unless record.send("#{field}_changed?".to_sym)