module Picky class Client # An ActiveRecord integration that uses the # Picky HTTP client to send index updates # back to a Picky server (usually Sinatra). # # Examples: # # Note that the Person will # # be indexed in three indexes. # # # class Person < ActiveRecord::Base # extend Picky::ActiveRecord.new # All attributes will be sent to index "people". # extend Picky::ActiveRecord.new('name') # Only the name will be sent to index "people". # extend Picky::ActiveRecord.new('surname', index: 'special_index') # Only the surname will be sent to index "special_index". # # Use the given Client to send index data. # # # extend Picky::ActiveRecord.new(client: Picky::Client.new(host: 'localhost', port: '4567', path: '/indexing')) # extend Picky::ActiveRecord.new(host: 'localhost', port: '4567', path: '/indexing') # end # # florian = Person.new name: "Florian", surname: "Hanke" # florian.save # florian.update_attributes name: "Peter" # class ActiveRecord < Module # Takes an array of indexed attributes/methods # and options. # # Note: See class documentation for a description. # # Examples: # Picky::Client::ActiveRecord.configure # Picky::Client::ActiveRecord.configure('name', 'surname', index: 'some_index_name') # # Options: # * index: The index name to save to. # * host: The host where the Picky server is. # * port: The host which the Picky server listens to. # * path: The path the Picky server uses for index updates (use e.f. extend Picky::Sinatra::IndexActions to open up a HTTP indexing interface). # * client: The client to use if you want to pass in your own (host, port, path options will be ignored). # def self.configure *attributes new *attributes end def initialize *attributes options = {} options = attributes.pop if attributes.last.respond_to?(:to_hash) # Default path for indexing is '/'. # client = options[:client] || (options[:path] ||= '/') && Picky::Client.new(options) index_name = options[:index] # Install. # install_extended_on client, index_name, attributes end # Installs an extended method on client which # handles the model passed to it. # def install_extended_on client, index_name, attributes self.class.send :define_method, :extended do |model| attributes = nil if attributes.empty? index_name ||= model.table_name # Only after the database has actually # updated the data do we want to index. # model.after_commit do |object| data = { 'id' => object.id } if object.destroyed? client.remove index_name, data else (attributes || object.attributes.keys).each do |attr| data[attr] = object.respond_to?(attr) && object.send(attr) || object[attr] end client.replace index_name, data end end end end end end end