Skip to content

Commit f39949d

Browse files
committed
[MODEL] Added a minimal working version of the model integration
Example for ActiveRecord ------------------------ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'pry' require 'logger' require 'ansi/core' require 'active_record' require 'elasticsearch/model' ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT) ActiveRecord::Base.establish_connection( adapter: 'sqlite3', database: ":memory:" ) ActiveRecord::Schema.define(version: 1) do create_table :articles do |t| t.string :title t.date :published_at t.timestamps end end class Article < ActiveRecord::Base end Article.__send__ :extend, Elasticsearch::Model::Searching::ClassMethods Article.create title: 'Foo' Article.create title: 'Bar' Article.create title: 'Foo Foo' response = Article.search 'foo'; Pry.start(binding, input: StringIO.new('response.records.to_a')) Example for Mongoid ------------------- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'pry' require 'logger' require 'ansi/core' require 'mongoid' require 'elasticsearch/model' Mongoid.logger.level = Logger::DEBUG Moped.logger.level = Logger::DEBUG Mongoid.connect_to 'articles' class Article include Mongoid::Document field :id, type: String field :title, type: String field :published_at, type: DateTime attr_accessible :id, :title, :published_at end Article.__send__ :extend, Elasticsearch::Model::Searching::ClassMethods Article.delete_all Article.create id: '1', title: 'Foo' Article.create id: '2', title: 'Bar' Article.create id: '3', title: 'Foo Foo' response = Article.search 'foo'; Pry.start(binding, input: StringIO.new('response.records.to_a'))
1 parent 26eb8b1 commit f39949d

File tree

8 files changed

+169
-1
lines changed

8 files changed

+169
-1
lines changed

Diff for: elasticsearch-model/elasticsearch-model.gemspec

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ Gem::Specification.new do |s|
2121
s.extra_rdoc_files = [ "README.md", "LICENSE.txt" ]
2222
s.rdoc_options = [ "--charset=UTF-8" ]
2323

24+
s.add_dependency "elasticsearch", '~> 0.4'
25+
s.add_dependency "hashie"
26+
2427
s.add_development_dependency "bundler", "~> 1.3"
2528
s.add_development_dependency "rake"
2629

Diff for: elasticsearch-model/lib/elasticsearch/model.rb

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
require "elasticsearch/model/version"
1+
require 'forwardable'
2+
3+
require 'elasticsearch'
4+
5+
require 'hashie'
6+
7+
require 'elasticsearch/model/response'
8+
require 'elasticsearch/model/response/base'
9+
require 'elasticsearch/model/response/result'
10+
require 'elasticsearch/model/response/results'
11+
require 'elasticsearch/model/response/records'
12+
require 'elasticsearch/model/searching'
13+
require 'elasticsearch/model/version'
214

315
module Elasticsearch
416
module Model
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module Elasticsearch
2+
module Model
3+
module Response
4+
class Response
5+
attr_reader :klass, :response
6+
7+
include Enumerable
8+
9+
extend Forwardable
10+
def_delegators :results, :each, :empty?, :size, :slice, :[], :to_ary
11+
12+
def initialize(klass, response)
13+
@klass = klass
14+
@response = response
15+
end
16+
17+
def results
18+
@results ||= Results.new(klass, response)
19+
end
20+
21+
def records
22+
@records ||= Records.new(klass, response)
23+
end
24+
25+
end
26+
end
27+
end
28+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module Elasticsearch
2+
module Model
3+
module Response
4+
module Base
5+
attr_reader :klass, :response
6+
7+
def initialize(klass, response)
8+
@klass = klass
9+
@response = response
10+
@total = response['total']
11+
@max_score = response['max_score']
12+
end
13+
14+
def results
15+
raise NoMethodError, "Abstract method called"
16+
end
17+
18+
def records
19+
raise NoMethodError, "Abstract method called"
20+
end
21+
22+
end
23+
end
24+
end
25+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module Elasticsearch
2+
module Model
3+
module Response
4+
class Records
5+
include Base
6+
7+
def initialize(klass, response)
8+
super
9+
@ids = response['hits']['hits'].map { |hit| hit['_id'] }
10+
end
11+
12+
def records
13+
@records = klass.find(@ids)
14+
end
15+
16+
# Delegate methods to `@records`
17+
#
18+
def method_missing(method_name, *arguments)
19+
records.respond_to?(method_name) ? records.__send__(method_name, *arguments) : super
20+
end
21+
22+
# Respond to methods from `@records`
23+
#
24+
def respond_to?(method_name, include_private = false)
25+
records.respond_to?(method_name) || super
26+
end
27+
28+
end
29+
end
30+
end
31+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module Elasticsearch
2+
module Model
3+
module Response
4+
class Result
5+
6+
def initialize(attributes)
7+
@result = Hashie::Mash.new(attributes)
8+
end
9+
10+
# Delegate methods to `@result`
11+
#
12+
def method_missing(method_name, *arguments)
13+
@result.respond_to?(method_name.to_sym) ? @result[method_name.to_sym] : super
14+
end
15+
16+
# Respond to methods from `@result`
17+
#
18+
def respond_to?(method_name, include_private = false)
19+
@result.has_key?(method_name.to_sym) || super
20+
end
21+
22+
# TODO: #to_s, #inspect, with support for Pry
23+
24+
end
25+
end
26+
end
27+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module Elasticsearch
2+
module Model
3+
module Response
4+
class Results
5+
include Base
6+
7+
attr_reader :klass, :results
8+
9+
include Enumerable
10+
11+
extend Forwardable
12+
def_delegators :results, :each, :empty?, :size, :slice, :[], :to_a, :to_ary
13+
14+
def initialize(klass, response)
15+
super
16+
@results = response['hits']['hits'].map { |hit| Result.new(hit) }
17+
end
18+
19+
end
20+
end
21+
end
22+
end
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module Elasticsearch
2+
module Model
3+
module Searching
4+
5+
module ClassMethods
6+
7+
def search(query_or_payload, options={})
8+
response = client.search index: self.model_name.collection, q: query_or_payload
9+
Response::Response.new(self, response)
10+
end
11+
12+
def client
13+
@client ||= Elasticsearch::Client.new
14+
end
15+
16+
end
17+
18+
end
19+
end
20+
end

0 commit comments

Comments
 (0)