elastic_record 1.1.8 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -1
- data/Gemfile +3 -1
- data/elastic_record.gemspec +1 -1
- data/lib/elastic_record/callbacks.rb +2 -0
- data/lib/elastic_record/connection.rb +5 -9
- data/lib/elastic_record/index/mapping.rb +2 -2
- data/lib/elastic_record/model.rb +1 -1
- data/lib/elastic_record/relation/search_methods.rb +0 -9
- data/lib/elastic_record/relation/value_methods.rb +1 -1
- data/lib/elastic_record/relation.rb +7 -26
- data/lib/elastic_record.rb +0 -1
- data/test/elastic_record/config_test.rb +1 -1
- data/test/elastic_record/connection_test.rb +2 -2
- data/test/elastic_record/index/mapping_test.rb +11 -1
- data/test/elastic_record/integration/active_record_test.rb +62 -25
- data/test/elastic_record/relation_test.rb +0 -47
- data/test/helper.rb +1 -7
- data/test/support/models/test_model.rb +1 -19
- data/test/support/models/warehouse.rb +0 -1
- data/test/support/models/widget.rb +0 -2
- metadata +11 -24
- data/lib/elastic_record/searches_many/association.rb +0 -149
- data/lib/elastic_record/searches_many/autosave.rb +0 -72
- data/lib/elastic_record/searches_many/builder.rb +0 -42
- data/lib/elastic_record/searches_many/collection_proxy.rb +0 -26
- data/lib/elastic_record/searches_many/reflection.rb +0 -45
- data/lib/elastic_record/searches_many.rb +0 -100
- data/test/elastic_record/searches_many/association_test.rb +0 -47
- data/test/elastic_record/searches_many/autosave_test.rb +0 -32
- data/test/elastic_record/searches_many/collection_proxy_test.rb +0 -23
- data/test/elastic_record/searches_many/reflection_test.rb +0 -33
- data/test/elastic_record/searches_many_test.rb +0 -76
- data/test/support/models/option.rb +0 -24
- data/test/support/query_counter.rb +0 -56
@@ -1,149 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/module/delegation'
|
2
|
-
|
3
|
-
module ElasticRecord
|
4
|
-
module SearchesMany
|
5
|
-
class Association
|
6
|
-
attr_reader :owner, :reflection, :collection
|
7
|
-
|
8
|
-
delegate :klass, :options, to: :reflection
|
9
|
-
|
10
|
-
def initialize(owner, reflection)
|
11
|
-
@owner = owner
|
12
|
-
@reflection = reflection
|
13
|
-
@collection = []
|
14
|
-
@loaded = false
|
15
|
-
end
|
16
|
-
|
17
|
-
def writer(other_records)
|
18
|
-
other_records = other_records.map do |other_record|
|
19
|
-
other_record.is_a?(Hash) ? klass.new(other_record) : other_record
|
20
|
-
end
|
21
|
-
|
22
|
-
delete(load_collection - other_records)
|
23
|
-
merge_collections(load_collection, other_records)
|
24
|
-
concat(other_records - load_collection)
|
25
|
-
|
26
|
-
if reflection.counter_cache_column
|
27
|
-
owner.send("#{reflection.counter_cache_column}=", other_records.size)
|
28
|
-
end
|
29
|
-
|
30
|
-
if reflection.touch_column
|
31
|
-
owner.send("#{reflection.touch_column}=", Time.current)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def reader
|
36
|
-
CollectionProxy.new(self)
|
37
|
-
end
|
38
|
-
|
39
|
-
def loaded?
|
40
|
-
@loaded
|
41
|
-
end
|
42
|
-
|
43
|
-
def concat(*records)
|
44
|
-
load_collection if owner.new_record?
|
45
|
-
|
46
|
-
result = true
|
47
|
-
|
48
|
-
records.flatten.each do |record|
|
49
|
-
add_to_collection(record) do |r|
|
50
|
-
result &&= record.save unless owner.new_record?
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
result && records
|
55
|
-
end
|
56
|
-
|
57
|
-
def delete(records)
|
58
|
-
records.each do |record|
|
59
|
-
callback(:before_remove, record)
|
60
|
-
|
61
|
-
if options[:autosave] || owner.new_record?
|
62
|
-
record.mark_for_destruction
|
63
|
-
else
|
64
|
-
record.destroy
|
65
|
-
end
|
66
|
-
|
67
|
-
callback(:after_remove, record)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def scope
|
72
|
-
search = klass.elastic_search.filter("#{reflection.belongs_to}_id" => owner.id).limit(1000000)
|
73
|
-
if options[:as]
|
74
|
-
search.filter! "#{reflection.belongs_to}_type" => owner.class.name
|
75
|
-
end
|
76
|
-
search
|
77
|
-
end
|
78
|
-
|
79
|
-
def load_collection
|
80
|
-
unless @loaded
|
81
|
-
@collection = merge_collections(persisted_collection, collection)
|
82
|
-
@loaded = true
|
83
|
-
end
|
84
|
-
|
85
|
-
collection
|
86
|
-
end
|
87
|
-
|
88
|
-
def eager_loaded_collection(records)
|
89
|
-
unless @loaded
|
90
|
-
@collection = records
|
91
|
-
@loaded = true
|
92
|
-
end
|
93
|
-
|
94
|
-
collection
|
95
|
-
end
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
def load_persisted_collection?
|
100
|
-
!loaded? || owner.new_record?
|
101
|
-
end
|
102
|
-
|
103
|
-
def persisted_collection
|
104
|
-
@persisted_collection ||= scope.to_a
|
105
|
-
end
|
106
|
-
|
107
|
-
def merge_collections(existing_records, new_records)
|
108
|
-
return existing_records if new_records.empty?
|
109
|
-
return new_records if existing_records.empty?
|
110
|
-
|
111
|
-
existing_records.map! do |existing_record|
|
112
|
-
if new_record = new_records.delete(existing_record)
|
113
|
-
(existing_record.attributes.keys - new_record.changes.keys).each do |name|
|
114
|
-
new_record.send("#{name}=", existing_record.send(name))
|
115
|
-
end
|
116
|
-
|
117
|
-
new_record
|
118
|
-
else
|
119
|
-
existing_record
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
existing_records + new_records
|
124
|
-
end
|
125
|
-
|
126
|
-
def add_to_collection(record)
|
127
|
-
callback(:before_add, record)
|
128
|
-
|
129
|
-
record.send("#{reflection.belongs_to}=", owner)
|
130
|
-
yield(record) if block_given?
|
131
|
-
@collection << record
|
132
|
-
|
133
|
-
callback(:after_add, record)
|
134
|
-
|
135
|
-
record
|
136
|
-
end
|
137
|
-
|
138
|
-
def callback(method, record)
|
139
|
-
reflection.callbacks[method].each do |callback|
|
140
|
-
if callback.respond_to?(:call)
|
141
|
-
callback.call(owner, record)
|
142
|
-
else
|
143
|
-
owner.send(callback, record)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
@@ -1,72 +0,0 @@
|
|
1
|
-
module ElasticRecord
|
2
|
-
module SearchesMany
|
3
|
-
module Autosave
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
module ClassMethods
|
7
|
-
def add_autosave_callbacks(reflection)
|
8
|
-
add_autosave_after_save_callbacks(reflection)
|
9
|
-
add_autosave_validation_callbacks(reflection)
|
10
|
-
end
|
11
|
-
|
12
|
-
def add_autosave_after_save_callbacks(reflection)
|
13
|
-
before_save { save_autosave_records(reflection) }
|
14
|
-
end
|
15
|
-
|
16
|
-
def add_autosave_validation_callbacks(reflection)
|
17
|
-
validate { validate_autosave_records(reflection) }
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def save_autosave_records(reflection)
|
23
|
-
if association = searches_many_instance_get(reflection.name)
|
24
|
-
associated_records_to_autosave(association).each do |record|
|
25
|
-
if record.marked_for_destruction?
|
26
|
-
record.destroy
|
27
|
-
elsif record.changed?
|
28
|
-
record.save
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def validate_autosave_records(reflection)
|
35
|
-
if association = searches_many_instance_get(reflection.name)
|
36
|
-
associated_records_to_autosave(association).each do |record|
|
37
|
-
unless record.valid?
|
38
|
-
record.errors.each do |attribute, message|
|
39
|
-
attribute = "#{reflection.name}.#{attribute}"
|
40
|
-
errors[attribute] << message
|
41
|
-
errors[attribute].uniq!
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def associated_records_to_autosave(association)
|
49
|
-
if association.loaded?
|
50
|
-
association.load_collection
|
51
|
-
else
|
52
|
-
[]
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# Marks this record to be destroyed as part of the parents save transaction.
|
57
|
-
# This does _not_ actually destroy the record instantly, rather child record will be destroyed
|
58
|
-
# when <tt>parent.save</tt> is called.
|
59
|
-
#
|
60
|
-
# Only useful if the <tt>:autosave</tt> option on the parent is enabled for this associated model.
|
61
|
-
def mark_for_destruction
|
62
|
-
@marked_for_destruction = true
|
63
|
-
end
|
64
|
-
|
65
|
-
# Returns whether or not this record will be destroyed as part of the parents save transaction.
|
66
|
-
#
|
67
|
-
# Only useful if the <tt>:autosave</tt> option on the parent is enabled for this associated model.
|
68
|
-
def marked_for_destruction?
|
69
|
-
@marked_for_destruction
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module ElasticRecord
|
2
|
-
module SearchesMany
|
3
|
-
class Builder
|
4
|
-
def self.build(model, name, options)
|
5
|
-
new(model, name, options).build
|
6
|
-
end
|
7
|
-
|
8
|
-
attr_reader :model, :name, :options
|
9
|
-
def initialize(model, name, options)
|
10
|
-
@model, @name, @options = model, name, options
|
11
|
-
end
|
12
|
-
|
13
|
-
def build
|
14
|
-
define_writer
|
15
|
-
define_reader
|
16
|
-
|
17
|
-
reflection = ElasticRecord::SearchesMany::Reflection.new(model, name, options)
|
18
|
-
model.searches_many_reflections = model.searches_many_reflections.merge(name => reflection)
|
19
|
-
|
20
|
-
model.add_autosave_callbacks(reflection) if options[:autosave]
|
21
|
-
end
|
22
|
-
|
23
|
-
def mixin
|
24
|
-
model.generated_searches_many_methods
|
25
|
-
end
|
26
|
-
|
27
|
-
def define_writer
|
28
|
-
name = self.name
|
29
|
-
mixin.redefine_method("#{name}=") do |records|
|
30
|
-
searches_many_association(name).writer(records)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def define_reader
|
35
|
-
name = self.name
|
36
|
-
mixin.redefine_method(name) do
|
37
|
-
searches_many_association(name).reader
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module ElasticRecord
|
2
|
-
module SearchesMany
|
3
|
-
class CollectionProxy < ElasticRecord::Relation
|
4
|
-
def initialize(association)
|
5
|
-
@association = association
|
6
|
-
super association.klass
|
7
|
-
merge! association.scope
|
8
|
-
end
|
9
|
-
|
10
|
-
def eager_loaded(records)
|
11
|
-
@association.eager_loaded_collection(records)
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_a
|
15
|
-
records = @association.load_collection.reject(&:destroyed?)
|
16
|
-
records = eager_load_associations(records) if eager_loading?
|
17
|
-
records
|
18
|
-
end
|
19
|
-
|
20
|
-
def <<(*records)
|
21
|
-
@association.concat(records) && self
|
22
|
-
end
|
23
|
-
alias_method :push, :<<
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module ElasticRecord
|
2
|
-
module SearchesMany
|
3
|
-
class Reflection
|
4
|
-
attr_reader :model, :name, :options
|
5
|
-
attr_reader :callbacks
|
6
|
-
def initialize(model, name, options)
|
7
|
-
@model, @name, @options = model, name, options
|
8
|
-
@callbacks = define_callbacks(options)
|
9
|
-
end
|
10
|
-
|
11
|
-
def klass
|
12
|
-
klass_name.constantize
|
13
|
-
end
|
14
|
-
|
15
|
-
def klass_name
|
16
|
-
options[:class_name] || name.to_s.classify
|
17
|
-
end
|
18
|
-
|
19
|
-
def belongs_to
|
20
|
-
options[:as] ? options[:as].to_s : model.name.to_s.demodulize.underscore
|
21
|
-
end
|
22
|
-
|
23
|
-
def foreign_key
|
24
|
-
options[:foreign_key] ? options[:foreign_key].to_s : "#{model.name.to_s.demodulize.underscore}_id"
|
25
|
-
end
|
26
|
-
|
27
|
-
CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove]
|
28
|
-
def define_callbacks(options)
|
29
|
-
Hash[CALLBACKS.map { |callback_name| [callback_name, Array(options[callback_name.to_sym])] }]
|
30
|
-
end
|
31
|
-
|
32
|
-
def touch_column
|
33
|
-
if options[:touch]
|
34
|
-
options[:touch] == true ? :updated_at : options[:touch].to_sym
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def counter_cache_column
|
39
|
-
if options[:counter_cache]
|
40
|
-
(options[:counter_cache] == true ? "#{name}_count" : options[:counter_cache]).to_sym
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,100 +0,0 @@
|
|
1
|
-
require 'elastic_record/searches_many/association'
|
2
|
-
require 'elastic_record/searches_many/autosave'
|
3
|
-
require 'elastic_record/searches_many/builder'
|
4
|
-
require 'elastic_record/searches_many/collection_proxy'
|
5
|
-
require 'elastic_record/searches_many/reflection'
|
6
|
-
|
7
|
-
module ElasticRecord
|
8
|
-
module SearchesMany
|
9
|
-
def self.included(base)
|
10
|
-
base.class_eval do
|
11
|
-
extend ClassMethods
|
12
|
-
|
13
|
-
class_attribute :searches_many_reflections
|
14
|
-
self.searches_many_reflections = {}
|
15
|
-
|
16
|
-
include ElasticRecord::SearchesMany::Autosave
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
module ClassMethods
|
21
|
-
# Specifies a one-to-many association. The following methods for retrieval and query of
|
22
|
-
# collections of associated objects will be added:
|
23
|
-
#
|
24
|
-
# [collection]
|
25
|
-
# Returns an array of all the associated objects.
|
26
|
-
# [collection=objects]
|
27
|
-
# Replaces the collections content by deleting and adding objects as appropriate.
|
28
|
-
# [collection_params=objects]
|
29
|
-
# Support for nested assignment from a form
|
30
|
-
# === Options
|
31
|
-
# [:as]
|
32
|
-
# Specifies a polymorphic interface (See <tt>belongs_to</tt>).
|
33
|
-
# [:touch]
|
34
|
-
# Specify to update the owner when changed. Specify <tt>true</tt>
|
35
|
-
# to update the updated_at field. If you specify a symbol, that attribute
|
36
|
-
# will be updated with the current time in addition to the updated_at/on attribute.
|
37
|
-
# [:autosave]
|
38
|
-
# If true, always save the associated objects or destroy them if marked for destruction, when
|
39
|
-
# saving the parent object.
|
40
|
-
# [:counter_cache]
|
41
|
-
# Caches the number of belonging objects on the associate class. This requires that a column
|
42
|
-
# named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class)
|
43
|
-
# is used on the associate class (such as a Post class). You can also specify a custom counter
|
44
|
-
# cache column by providing a column name instead of a +true+/+false+ value to this
|
45
|
-
# option (e.g., <tt>:counter_cache => :my_custom_counter</tt>.)
|
46
|
-
# [:class_name]
|
47
|
-
# Specify the class name of the association. Use it only if that name can't be inferred
|
48
|
-
# from the association name. So <tt>has_one :manager</tt> will by default be linked to the Manager class, but
|
49
|
-
# if the real class name is Person, you'll have to specify it with this option.
|
50
|
-
#
|
51
|
-
# === Example
|
52
|
-
#
|
53
|
-
# Example: A Firm class declares <tt>has_many :clients</tt>, which will add:
|
54
|
-
# * <tt>Firm#clients</tt>
|
55
|
-
# * <tt>Firm#clients=(objects)</tt>
|
56
|
-
# * <tt>Firm#client_params=(params)</tt>
|
57
|
-
def searches_many(name, options = {})
|
58
|
-
ElasticRecord::SearchesMany::Builder.build(self, name, options)
|
59
|
-
end
|
60
|
-
|
61
|
-
def generated_searches_many_methods
|
62
|
-
@generated_searches_many_methods ||= begin
|
63
|
-
mod = const_set(:GeneratedSearchesManyMethods, Module.new)
|
64
|
-
include mod
|
65
|
-
mod
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# Returns the searches_many instance for the given name, instantiating it if it doesn't already exist
|
71
|
-
def searches_many_association(name)
|
72
|
-
association = searches_many_instance_get(name)
|
73
|
-
|
74
|
-
if association.nil?
|
75
|
-
association = ElasticRecord::SearchesMany::Association.new(self, searches_many_reflections[name])
|
76
|
-
searches_many_instance_set(name, association)
|
77
|
-
end
|
78
|
-
|
79
|
-
association
|
80
|
-
end
|
81
|
-
|
82
|
-
def reload
|
83
|
-
super
|
84
|
-
searches_many_cache.clear
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
def searches_many_cache
|
89
|
-
@searches_many_cache ||= {}
|
90
|
-
end
|
91
|
-
|
92
|
-
def searches_many_instance_get(name)
|
93
|
-
searches_many_cache[name.to_sym]
|
94
|
-
end
|
95
|
-
|
96
|
-
def searches_many_instance_set(name, association)
|
97
|
-
searches_many_cache[name.to_sym] = association
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class ElasticRecord::SearchesMany::AssociationTest < MiniTest::Spec
|
4
|
-
|
5
|
-
def test_writer_assignment_from_hash
|
6
|
-
warehouse = Warehouse.new
|
7
|
-
warehouse.widgets = [{color: 'blue', name: 'thing'}]
|
8
|
-
|
9
|
-
assert_equal 1, warehouse.widgets.all.count
|
10
|
-
expected = {
|
11
|
-
'color' => 'blue',
|
12
|
-
'name' => 'thing',
|
13
|
-
'warehouse_id' => warehouse.id,
|
14
|
-
}
|
15
|
-
assert_equal expected, warehouse.widgets[0].attributes
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_writer
|
19
|
-
warehouse = Warehouse.new
|
20
|
-
|
21
|
-
warehouse.widgets = [{color: 'blue', name: 'thing'}]
|
22
|
-
|
23
|
-
assert_equal 1, warehouse.widgets.all.count
|
24
|
-
|
25
|
-
warehouse.widgets = [ {color: 'red', name: 'device'}, {color: 'blue', name: 'thing'} ]
|
26
|
-
|
27
|
-
assert_equal 3, warehouse.widgets.all.count
|
28
|
-
assert warehouse.widgets[0].marked_for_destruction?
|
29
|
-
refute warehouse.widgets[1].marked_for_destruction?
|
30
|
-
refute warehouse.widgets[2].marked_for_destruction?
|
31
|
-
|
32
|
-
expected = {
|
33
|
-
'color' => 'red',
|
34
|
-
'name' => 'device',
|
35
|
-
'warehouse_id' => warehouse.id,
|
36
|
-
}
|
37
|
-
assert_equal expected, warehouse.widgets[1].attributes
|
38
|
-
|
39
|
-
expected = {
|
40
|
-
'color' => 'blue',
|
41
|
-
'name' => 'thing',
|
42
|
-
'warehouse_id' => warehouse.id,
|
43
|
-
}
|
44
|
-
assert_equal expected, warehouse.widgets[2].attributes
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class ElasticRecord::SearchesMany::AutosaveTest < MiniTest::Unit::TestCase
|
4
|
-
def test_save_associations_autosave_callback
|
5
|
-
warehouse = Warehouse.new
|
6
|
-
widget = Widget.new
|
7
|
-
warehouse.widgets = [widget]
|
8
|
-
assert warehouse.new_record?
|
9
|
-
assert widget.new_record?
|
10
|
-
|
11
|
-
warehouse.save
|
12
|
-
|
13
|
-
assert widget.persisted?
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_validate_associations_autosave_callback
|
17
|
-
warehouse = Warehouse.new
|
18
|
-
widget = Widget.new color: 123
|
19
|
-
warehouse.widgets = [widget]
|
20
|
-
|
21
|
-
assert warehouse.invalid?
|
22
|
-
assert_equal ["is invalid"], warehouse.errors['widgets.color']
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_mark_for_destruction
|
26
|
-
widget = Widget.new
|
27
|
-
|
28
|
-
widget.mark_for_destruction
|
29
|
-
|
30
|
-
assert widget.marked_for_destruction?
|
31
|
-
end
|
32
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class ElasticRecord::SearchesMany::CollectionProxyTest < MiniTest::Unit::TestCase
|
4
|
-
def test_add_to_new_record
|
5
|
-
warehouse = Warehouse.new
|
6
|
-
widget = Widget.new
|
7
|
-
|
8
|
-
warehouse.widgets << widget
|
9
|
-
|
10
|
-
assert widget.new_record?
|
11
|
-
assert_equal [widget], warehouse.widgets
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_add_to_persisted_record
|
15
|
-
warehouse = Warehouse.create
|
16
|
-
widget = Widget.new
|
17
|
-
|
18
|
-
warehouse.widgets << widget
|
19
|
-
|
20
|
-
assert !widget.new_record?
|
21
|
-
assert_equal [widget], warehouse.widgets
|
22
|
-
end
|
23
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class ElasticRecord::SearchesMany::ReflectionTest < MiniTest::Unit::TestCase
|
4
|
-
|
5
|
-
def test_foreiegn_key
|
6
|
-
assert_equal 'warehouse_id', reflection_class.new(Warehouse, :widgets, {}).foreign_key
|
7
|
-
assert_equal 'foo_id', reflection_class.new(Warehouse, :widgets, {:foreign_key => 'foo_id' }).foreign_key
|
8
|
-
end
|
9
|
-
|
10
|
-
def test_klass_name
|
11
|
-
assert_equal 'Product', reflection_class.new(Warehouse, :widgets, {class_name: 'Product'}).klass_name
|
12
|
-
assert_equal 'Widget', reflection_class.new(Warehouse, :widgets, {}).klass_name
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_touch_column
|
16
|
-
assert_nil reflection_class.new(Warehouse, :widgets, {}).touch_column
|
17
|
-
assert_equal :updated_at, reflection_class.new(Warehouse, :widgets, touch: true).touch_column
|
18
|
-
assert_equal :my_column, reflection_class.new(Warehouse, :widgets, touch: :my_column).touch_column
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_counter_cache_column
|
22
|
-
assert_nil reflection_class.new(Warehouse, :widgets, {}).counter_cache_column
|
23
|
-
assert_equal :widgets_count, reflection_class.new(Warehouse, :widgets, counter_cache: true).counter_cache_column
|
24
|
-
assert_equal :my_column, reflection_class.new(Warehouse, :widgets, counter_cache: :my_column).counter_cache_column
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def reflection_class
|
30
|
-
ElasticRecord::SearchesMany::Reflection
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class ElasticRecord::SearchesManyTest < MiniTest::Unit::TestCase
|
4
|
-
def test_reader
|
5
|
-
warehouse = Warehouse.create
|
6
|
-
related_widget = Widget.create warehouse: warehouse
|
7
|
-
unrelated_widget = Widget.create
|
8
|
-
|
9
|
-
assert_equal [related_widget], warehouse.widgets
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_write_with_objects
|
13
|
-
warehouse = Warehouse.new
|
14
|
-
widget = Widget.new
|
15
|
-
|
16
|
-
warehouse.widgets = [widget]
|
17
|
-
|
18
|
-
assert widget.new_record?
|
19
|
-
assert_equal warehouse.id, widget.warehouse_id
|
20
|
-
# assert_equal 1, warehouse.widgets_count
|
21
|
-
# assert_in_delta Time.current, warehouse.widgets_updated_at, 5
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_write_with_attributes
|
25
|
-
warehouse = Warehouse.new
|
26
|
-
|
27
|
-
warehouse.widgets = [
|
28
|
-
{
|
29
|
-
color: 'blue',
|
30
|
-
name: 'Toy'
|
31
|
-
}
|
32
|
-
]
|
33
|
-
|
34
|
-
widgets = warehouse.widgets
|
35
|
-
assert_equal 1, widgets.size
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_write_marks_destroyed
|
39
|
-
warehouse = Warehouse.new
|
40
|
-
widget = Widget.create warehouse: warehouse
|
41
|
-
|
42
|
-
warehouse.widgets = []
|
43
|
-
|
44
|
-
association = warehouse.searches_many_association(:widgets)
|
45
|
-
assert_equal 1, association.reader.size
|
46
|
-
assert association.reader.first.marked_for_destruction?
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_write_existing_record
|
50
|
-
widget = Widget.create name: 'Toy', color: 'green'
|
51
|
-
warehouse = Warehouse.new widgets: [widget]
|
52
|
-
|
53
|
-
warehouse.widgets = [
|
54
|
-
{
|
55
|
-
id: widget.id,
|
56
|
-
color: "blue"
|
57
|
-
}
|
58
|
-
]
|
59
|
-
|
60
|
-
widgets = warehouse.widgets
|
61
|
-
assert_equal 1, widgets.size
|
62
|
-
assert_equal "blue", widgets.first.color
|
63
|
-
assert_equal "Toy", widgets.first.name
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_reload
|
67
|
-
warehouse = Warehouse.create
|
68
|
-
widget = Widget.create name: 'Toy', color: 'green', warehouse: warehouse
|
69
|
-
assert_equal [widget], warehouse.widgets
|
70
|
-
widget.destroy
|
71
|
-
|
72
|
-
warehouse.reload
|
73
|
-
|
74
|
-
assert_equal [], warehouse.widgets
|
75
|
-
end
|
76
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
class Option
|
2
|
-
include TestModel
|
3
|
-
|
4
|
-
define_attributes [:name, :widget_id]
|
5
|
-
|
6
|
-
searches_many :options
|
7
|
-
|
8
|
-
self.elastic_index.mapping[:properties].update(
|
9
|
-
name: {
|
10
|
-
type: 'multi_field',
|
11
|
-
fields: {
|
12
|
-
name: {type: 'string', index: 'not_analyzed'},
|
13
|
-
analyzed: {type: 'string', index: 'analyzed'}
|
14
|
-
}
|
15
|
-
},
|
16
|
-
widget_id: {
|
17
|
-
type: 'string', index: 'not_analyzed'
|
18
|
-
}
|
19
|
-
)
|
20
|
-
|
21
|
-
def widget=(other)
|
22
|
-
self.widget_id = other.id
|
23
|
-
end
|
24
|
-
end
|