forked from floere/picky
/
active_record.rb
87 lines (75 loc) · 3.09 KB
/
active_record.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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.new
# Picky::Client::ActiveRecord.new('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 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)
self.class.class_eval do
index_name = options[:index]
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
end