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)