Skip to content

Commit 936be78

Browse files
committed
[MODEL] Added integration test for ActiveRecord associations modeled with parent/child
1 parent 4e59ee2 commit 936be78

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
require 'test_helper'
2+
3+
class Question < ActiveRecord::Base
4+
include Elasticsearch::Model
5+
6+
has_many :answers, dependent: :destroy
7+
8+
index_name 'questions_and_answers'
9+
10+
mapping do
11+
indexes :title
12+
indexes :text
13+
indexes :author
14+
end
15+
16+
after_commit lambda { __elasticsearch__.index_document }, on: :create
17+
after_commit lambda { __elasticsearch__.update_document }, on: :update
18+
after_commit lambda { __elasticsearch__.delete_document }, on: :destroy
19+
end
20+
21+
class Answer < ActiveRecord::Base
22+
include Elasticsearch::Model
23+
24+
belongs_to :question
25+
26+
index_name 'questions_and_answers'
27+
28+
mapping _parent: { type: 'question', required: true } do
29+
indexes :text
30+
indexes :author
31+
end
32+
33+
after_commit lambda { __elasticsearch__.index_document(parent: question_id) }, on: :create
34+
after_commit lambda { __elasticsearch__.update_document(parent: question_id) }, on: :update
35+
after_commit lambda { __elasticsearch__.delete_document(parent: question_id) }, on: :destroy
36+
end
37+
38+
module ParentChildSearchable
39+
INDEX_NAME = 'questions_and_answers'
40+
41+
def create_index!(options={})
42+
client = Question.__elasticsearch__.client
43+
client.indices.delete index: INDEX_NAME rescue nil if options[:force]
44+
45+
settings = Question.settings.to_hash.merge Answer.settings.to_hash
46+
mappings = Question.mappings.to_hash.merge Answer.mappings.to_hash
47+
48+
client.indices.create index: INDEX_NAME,
49+
body: {
50+
settings: settings.to_hash,
51+
mappings: mappings.to_hash }
52+
end
53+
54+
extend self
55+
end
56+
57+
module Elasticsearch
58+
module Model
59+
class ActiveRecordAssociationsParentChildIntegrationTest < Elasticsearch::Test::IntegrationTestCase
60+
61+
context "ActiveRecord associations with parent/child modelling" do
62+
setup do
63+
ActiveRecord::Schema.define(version: 1) do
64+
create_table :questions do |t|
65+
t.string :title
66+
t.text :text
67+
t.string :author
68+
t.timestamps
69+
end
70+
create_table :answers do |t|
71+
t.text :text
72+
t.string :author
73+
t.references :question
74+
t.timestamps
75+
end and add_index(:answers, :question_id)
76+
end
77+
78+
Question.delete_all
79+
ParentChildSearchable.create_index! force: true
80+
81+
q_1 = Question.create! title: 'First Question', author: 'John'
82+
q_2 = Question.create! title: 'Second Question', author: 'Jody'
83+
84+
q_1.answers.create! text: 'Lorem Ipsum', author: 'Adam'
85+
q_1.answers.create! text: 'Dolor Sit', author: 'Ryan'
86+
87+
q_2.answers.create! text: 'Amet Et', author: 'John'
88+
89+
Question.__elasticsearch__.refresh_index!
90+
end
91+
92+
should "find questions by matching answers" do
93+
response = Question.search(
94+
{ query: {
95+
has_child: {
96+
type: 'answer',
97+
query: {
98+
match: {
99+
author: 'john'
100+
}
101+
}
102+
}
103+
}
104+
})
105+
106+
assert_equal 'Second Question', response.records.first.title
107+
end
108+
109+
should "find answers for matching questions" do
110+
response = Answer.search(
111+
{ query: {
112+
has_parent: {
113+
parent_type: 'question',
114+
query: {
115+
match: {
116+
author: 'john'
117+
}
118+
}
119+
}
120+
}
121+
})
122+
123+
assert_same_elements ['Adam', 'Ryan'], response.records.map(&:author)
124+
end
125+
126+
should "delete answers when the question is deleted" do
127+
Question.where(title: 'First Question').each(&:destroy)
128+
Question.__elasticsearch__.refresh_index!
129+
130+
response = Answer.search query: { match_all: {} }
131+
132+
assert_equal 1, response.results.total
133+
end
134+
end
135+
136+
end
137+
end
138+
end

0 commit comments

Comments
 (0)