# Copyright (c) 2006 Surendra K. Singhi # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA require 'active_record' require 'classifier' module ActiveRecord # :nodoc: module Acts #:nodoc: module Classifiable def self.included(base) # :nodoc: base.extend(ClassMethods) end module ClassMethods def acts_as_classifiable(options = {}) write_inheritable_attribute(:acts_as_classifiable_options, { :fields => options[:fields], :categories => options[:categories] }) class_inheritable_reader :acts_as_classifiable_options include ActiveRecord::Acts::Classifiable::InstanceMethods extend ActiveRecord::Acts::Classifiable::SingletonMethods end def classifier_record(identifier = nil) record = find_classifier_record(identifier) if record record.load_classifier else record = ClassifierModel.new record.classifiable_type = self.to_s record.identifier = identifier record.classifier = Classifier::Bayes.new(*(acts_as_classifiable_options[:categories])) end return record end end module SingletonMethods def find_classifier_record(identifier = nil) ClassifierModel.find_by_classifiable_type_and_identifier(self.to_s,identifier) end def method_missing(name, *args) if name.to_s =~ /^(un)?train$/ categories = args[0] instances = args[1] identifier = args[2] record = classifier_record(identifier) 0.upto(instances.size - 1) do |i| acts_as_classifiable_options[:fields].each do |field| record.classifier.send(name.to_s,categories[i],instances[i].send(field)) end end record.save elsif name.to_s =~ /^(un)?train_/ category = name.to_s.gsub(/(un)?train_([\w]+)/, '\2').prepare_category_name instances = args[0] identifier = args[1] record = classifier_record(identifier) instances.each do |inst| acts_as_classifiable_options[:fields].each {|field| record.classifier.send(name.to_s,inst.send(field))} end record.save elsif name.to_s == "classifications" || name.to_s == "classify" instances = args[0] identifier = args[1] record = classifier_record(identifier) results = [] instances.each do |inst| results << record.classifier.send(name.to_s, inst.collated_classification_text) end return results else super end end end module InstanceMethods def method_missing(name, *args) if name.to_s =~ /^(un)?train$/ category = args[0] identifier = args[1] record = self.class.classifier_record(identifier) acts_as_classifiable_options[:fields].each{|field| record.classifier.send(name.to_s,category,self.send(field))} record.save elsif name.to_s =~ /^(un)?train_/ identifier = args[0] record = self.class.classifier_record(identifier) acts_as_classifiable_options[:fields].each{|field| record.classifier.send(name.to_s,self.send(field))} record.save elsif name.to_s == "classifications" || name.to_s == "classify" identifier = args[0] record = self.class.classifier_record(identifier) return record.classifier.send(name.to_s, collated_classification_text) else super end end def collated_classification_text acts_as_classifiable_options[:fields].collect{|field| self.send(field)}.join(" ") end end end end end