chewy 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +0 -1
- data/.travis.yml +2 -2
- data/Appraisals +6 -2
- data/CHANGELOG.md +29 -1
- data/Gemfile +4 -0
- data/README.md +137 -19
- data/chewy.gemspec +1 -0
- data/gemfiles/rails.3.2.activerecord.gemfile +2 -0
- data/gemfiles/rails.3.2.activerecord.kaminari.gemfile +1 -1
- data/gemfiles/rails.4.0.activerecord.gemfile +2 -0
- data/gemfiles/rails.4.0.activerecord.kaminari.gemfile +1 -1
- data/gemfiles/rails.4.0.mongoid.gemfile +2 -0
- data/gemfiles/rails.4.0.mongoid.kaminari.gemfile +1 -1
- data/gemfiles/rails.4.1.activerecord.gemfile +2 -0
- data/gemfiles/rails.4.1.activerecord.kaminari.gemfile +1 -1
- data/gemfiles/rails.4.1.mongoid.gemfile +2 -0
- data/gemfiles/rails.4.1.mongoid.kaminari.gemfile +1 -1
- data/gemfiles/rails.4.2.activerecord.gemfile +2 -0
- data/gemfiles/rails.4.2.activerecord.kaminari.gemfile +1 -1
- data/gemfiles/rails.4.2.mongoid.gemfile +2 -0
- data/gemfiles/rails.4.2.mongoid.kaminari.gemfile +1 -1
- data/lib/chewy.rb +1 -2
- data/lib/chewy/config.rb +3 -3
- data/lib/chewy/fields/base.rb +27 -30
- data/lib/chewy/fields/root.rb +9 -19
- data/lib/chewy/query.rb +34 -1
- data/lib/chewy/railtie.rb +1 -0
- data/lib/chewy/rspec/update_index.rb +16 -6
- data/lib/chewy/strategy.rb +12 -0
- data/lib/chewy/strategy/atomic.rb +1 -1
- data/lib/chewy/strategy/resque.rb +26 -0
- data/lib/chewy/strategy/sidekiq.rb +26 -0
- data/lib/chewy/strategy/urgent.rb +1 -1
- data/lib/chewy/type.rb +2 -0
- data/lib/chewy/type/adapter/active_record.rb +7 -3
- data/lib/chewy/type/adapter/mongoid.rb +5 -0
- data/lib/chewy/type/adapter/orm.rb +1 -1
- data/lib/chewy/type/crutch.rb +31 -0
- data/lib/chewy/type/import.rb +7 -6
- data/lib/chewy/type/mapping.rb +7 -3
- data/lib/chewy/type/observe.rb +24 -35
- data/lib/chewy/version.rb +1 -1
- data/spec/chewy/fields/base_spec.rb +26 -19
- data/spec/chewy/query_spec.rb +13 -0
- data/spec/chewy/runtime_spec.rb +1 -1
- data/spec/chewy/strategy/resque_spec.rb +35 -0
- data/spec/chewy/strategy/sidekiq_spec.rb +35 -0
- data/spec/chewy/type/adapter/mongoid_spec.rb +18 -9
- data/spec/chewy/type/mapping_spec.rb +14 -9
- data/spec/chewy/type/observe_spec.rb +22 -7
- data/spec/spec_helper.rb +1 -0
- metadata +23 -2
@@ -0,0 +1,31 @@
|
|
1
|
+
module Chewy
|
2
|
+
class Type
|
3
|
+
module Crutch
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :_crutches
|
8
|
+
self._crutches = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
class Crutches
|
12
|
+
def initialize type, collection
|
13
|
+
@type, @collection = type, collection
|
14
|
+
@type._crutches.keys.each do |name|
|
15
|
+
singleton_class.class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
16
|
+
def #{name}
|
17
|
+
@#{name} ||= @type._crutches[:#{name}].call @collection
|
18
|
+
end
|
19
|
+
METHOD
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
def crutch name, &block
|
26
|
+
self._crutches = _crutches.merge(name.to_sym => block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/chewy/type/import.rb
CHANGED
@@ -78,11 +78,12 @@ module Chewy
|
|
78
78
|
def bulk_body(action_objects, indexed_objects = nil)
|
79
79
|
action_objects.inject([]) do |result, (action, objects)|
|
80
80
|
method = "#{action}_bulk_entry"
|
81
|
-
|
81
|
+
crutches = Chewy::Type::Crutch::Crutches.new self, objects
|
82
|
+
result.concat(objects.map { |object| send(method, object, indexed_objects, crutches) }.flatten)
|
82
83
|
end
|
83
84
|
end
|
84
85
|
|
85
|
-
def delete_bulk_entry(object, indexed_objects = nil)
|
86
|
+
def delete_bulk_entry(object, indexed_objects = nil, crutches = nil)
|
86
87
|
entry = {}
|
87
88
|
|
88
89
|
if self.root_object.id
|
@@ -102,7 +103,7 @@ module Chewy
|
|
102
103
|
[{ delete: entry }]
|
103
104
|
end
|
104
105
|
|
105
|
-
def index_bulk_entry(object, indexed_objects = nil)
|
106
|
+
def index_bulk_entry(object, indexed_objects = nil, crutches = nil)
|
106
107
|
entry = {}
|
107
108
|
|
108
109
|
if self.root_object.id
|
@@ -119,7 +120,7 @@ module Chewy
|
|
119
120
|
existing_object = entry[:_id].present? && indexed_objects && indexed_objects[entry[:_id].to_s]
|
120
121
|
end
|
121
122
|
|
122
|
-
entry[:data] = object_data(object)
|
123
|
+
entry[:data] = object_data(object, crutches)
|
123
124
|
|
124
125
|
if existing_object && entry[:parent].to_s != existing_object[:parent]
|
125
126
|
[{ delete: entry.except(:data).merge(parent: existing_object[:parent]) }, { index: entry }]
|
@@ -148,8 +149,8 @@ module Chewy
|
|
148
149
|
end
|
149
150
|
end
|
150
151
|
|
151
|
-
def object_data object
|
152
|
-
(self.root_object ||= build_root).compose(object)[type_name.to_sym]
|
152
|
+
def object_data object, crutches = nil
|
153
|
+
(self.root_object ||= build_root).compose(object, crutches)[type_name.to_sym]
|
153
154
|
end
|
154
155
|
|
155
156
|
def extract_errors result
|
data/lib/chewy/type/mapping.rb
CHANGED
@@ -154,7 +154,11 @@ module Chewy
|
|
154
154
|
private
|
155
155
|
|
156
156
|
def expand_nested field, &block
|
157
|
-
|
157
|
+
if @_current_field
|
158
|
+
field.parent = @_current_field
|
159
|
+
@_current_field.children.push(field)
|
160
|
+
end
|
161
|
+
|
158
162
|
if block
|
159
163
|
previous_field, @_current_field = @_current_field, field
|
160
164
|
block.call
|
@@ -164,8 +168,8 @@ module Chewy
|
|
164
168
|
|
165
169
|
def build_root options = {}, &block
|
166
170
|
self.root_object = Chewy::Fields::Root.new(type_name, options)
|
167
|
-
expand_nested(
|
168
|
-
@_current_field =
|
171
|
+
expand_nested(root_object, &block)
|
172
|
+
@_current_field = root_object
|
169
173
|
end
|
170
174
|
end
|
171
175
|
end
|
data/lib/chewy/type/observe.rb
CHANGED
@@ -3,52 +3,41 @@ module Chewy
|
|
3
3
|
module Observe
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
instance_eval(&block)
|
18
|
-
end
|
19
|
-
|
20
|
-
Chewy.derive_type(type_name).update_index(backreference, options)
|
6
|
+
def self.update_proc(type_name, *args, &block)
|
7
|
+
options = args.extract_options!
|
8
|
+
method = args.first
|
9
|
+
|
10
|
+
Proc.new do
|
11
|
+
backreference = if method && method.to_s == 'self'
|
12
|
+
self
|
13
|
+
elsif method
|
14
|
+
send(method)
|
15
|
+
else
|
16
|
+
instance_eval(&block)
|
21
17
|
end
|
22
18
|
|
23
|
-
|
24
|
-
after_destroy &update
|
19
|
+
Chewy.derive_type(type_name).update_index(backreference, options)
|
25
20
|
end
|
26
21
|
end
|
27
22
|
|
28
|
-
module
|
23
|
+
module MongoidMethods
|
29
24
|
def update_index(type_name, *args, &block)
|
30
|
-
|
31
|
-
method = args.first
|
25
|
+
update_proc = Observe.update_proc(type_name, *args, &block)
|
32
26
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
self
|
38
|
-
elsif method
|
39
|
-
send(method)
|
40
|
-
else
|
41
|
-
instance_eval(&block)
|
42
|
-
end
|
27
|
+
after_save &update_proc
|
28
|
+
after_destroy &update_proc
|
29
|
+
end
|
30
|
+
end
|
43
31
|
|
44
|
-
|
45
|
-
|
32
|
+
module ActiveRecordMethods
|
33
|
+
def update_index(type_name, *args, &block)
|
34
|
+
update_proc = Observe.update_proc(type_name, *args, &block)
|
46
35
|
|
47
36
|
if Chewy.use_after_commit_callbacks
|
48
|
-
after_commit &
|
37
|
+
after_commit &update_proc
|
49
38
|
else
|
50
|
-
after_save &
|
51
|
-
after_destroy &
|
39
|
+
after_save &update_proc
|
40
|
+
after_destroy &update_proc
|
52
41
|
end
|
53
42
|
end
|
54
43
|
end
|
data/lib/chewy/version.rb
CHANGED
@@ -14,9 +14,9 @@ describe Chewy::Fields::Base do
|
|
14
14
|
|
15
15
|
context 'nested fields' do
|
16
16
|
before do
|
17
|
-
field.
|
18
|
-
field.
|
19
|
-
field.
|
17
|
+
field.children.push(described_class.new(:subname1, value: ->(o){ o.subvalue1 }))
|
18
|
+
field.children.push(described_class.new(:subname2, value: ->{ subvalue2 }))
|
19
|
+
field.children.push(described_class.new(:subname3))
|
20
20
|
end
|
21
21
|
|
22
22
|
specify { expect(field.compose(double(value: double(subvalue1: 'hello', subvalue2: 'value', subname3: 'world'))))
|
@@ -32,8 +32,13 @@ describe Chewy::Fields::Base do
|
|
32
32
|
|
33
33
|
context 'parent objects' do
|
34
34
|
let!(:country) { described_class.new(:name, value: ->(country){ country.cities }) }
|
35
|
-
let!(:city) {
|
36
|
-
let!(:district) {
|
35
|
+
let!(:city) { described_class.new(:name, value: ->(city, country) { city.districts.map { |district| [district, country.name] } }) }
|
36
|
+
let!(:district) { described_class.new(:name, value: ->(district, city, country) { [district, city.name, country.name] }) }
|
37
|
+
|
38
|
+
before do
|
39
|
+
country.children.push(city)
|
40
|
+
city.children.push(district)
|
41
|
+
end
|
37
42
|
|
38
43
|
specify { expect(country.compose(double(name: 'Thailand', cities: [
|
39
44
|
double(name: 'Bangkok', districts: ['First', 'Second'])
|
@@ -48,8 +53,8 @@ describe Chewy::Fields::Base do
|
|
48
53
|
context 'implicit values' do
|
49
54
|
let(:field) { described_class.new(:name, type: 'string') }
|
50
55
|
before do
|
51
|
-
field.
|
52
|
-
field.
|
56
|
+
field.children.push(described_class.new(:name))
|
57
|
+
field.children.push(described_class.new(:untouched))
|
53
58
|
end
|
54
59
|
|
55
60
|
specify { expect(field.compose(double(name: 'Alex'))).to eq({name: 'Alex'}) }
|
@@ -60,28 +65,21 @@ describe Chewy::Fields::Base do
|
|
60
65
|
let(:object) { double(name: { key1: 'value1', key2: 'value2' }) }
|
61
66
|
|
62
67
|
before do
|
63
|
-
field.
|
64
|
-
field.
|
68
|
+
field.children.push(described_class.new(:key1, value: ->(h){ h[:key1] }))
|
69
|
+
field.children.push(described_class.new(:key2, value: ->(h){ h[:key2] }))
|
65
70
|
end
|
66
71
|
|
67
72
|
specify{ expect(field.compose(object)).to eq({ name: { 'key1' => 'value1', 'key2' => 'value2' } }) }
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
71
|
-
describe '#nested' do
|
72
|
-
let(:field) { described_class.new(:name) }
|
73
|
-
|
74
|
-
specify { expect { field.nested(described_class.new(:name1)) }
|
75
|
-
.to change { field.nested[:name1] }.from(nil).to(an_instance_of(described_class)) }
|
76
|
-
end
|
77
|
-
|
78
76
|
describe '#mappings_hash' do
|
79
77
|
let(:field) { described_class.new(:name, type: :object) }
|
80
78
|
let(:fields1) { 2.times.map { |i| described_class.new("name#{i+1}", type: "string#{i+1}") } }
|
81
79
|
let(:fields2) { 2.times.map { |i| described_class.new("name#{i+3}", type: "string#{i+3}") } }
|
82
80
|
before do
|
83
|
-
fields1.each { |m| field.
|
84
|
-
fields2.each { |m| fields1[0].
|
81
|
+
fields1.each { |m| field.children.push(m) }
|
82
|
+
fields2.each { |m| fields1[0].children.push(m) }
|
85
83
|
end
|
86
84
|
|
87
85
|
specify { expect(field.mappings_hash).to eq({name: {type: :object, properties: {
|
@@ -317,7 +315,16 @@ describe Chewy::Fields::Base do
|
|
317
315
|
stub_model(:country)
|
318
316
|
|
319
317
|
City.belongs_to :country
|
320
|
-
|
318
|
+
|
319
|
+
if active_record?
|
320
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
321
|
+
Country.has_many :cities, -> { order :id }
|
322
|
+
else
|
323
|
+
Country.has_many :cities, order: :id
|
324
|
+
end
|
325
|
+
else # mongoid
|
326
|
+
Country.has_many :cities, order: :id.asc
|
327
|
+
end
|
321
328
|
|
322
329
|
stub_index(:countries) do
|
323
330
|
define_type Country do
|
data/spec/chewy/query_spec.rb
CHANGED
@@ -39,6 +39,8 @@ describe Chewy::Query do
|
|
39
39
|
specify { expect(subject.types(:product, :country).count).to eq(6) }
|
40
40
|
specify { expect(subject.filter(term: {age: 10}).count).to eq(1) }
|
41
41
|
specify { expect(subject.query(term: {age: 10}).count).to eq(1) }
|
42
|
+
specify { expect(subject.search_type(:count).count).to eq(0) }
|
43
|
+
specify { expect(subject.search_type(:count).total).to eq(9) }
|
42
44
|
end
|
43
45
|
|
44
46
|
describe '#==' do
|
@@ -101,6 +103,13 @@ describe Chewy::Query do
|
|
101
103
|
specify { expect { subject.offset(10) }.not_to change { subject.criteria.request_options } }
|
102
104
|
end
|
103
105
|
|
106
|
+
describe '#script_fields' do
|
107
|
+
specify { expect(subject.script_fields(distance: 'test()')).to be_a described_class }
|
108
|
+
specify { expect(subject.script_fields(distance: 'test()')).not_to eq(subject) }
|
109
|
+
specify { expect(subject.script_fields(distance: 'test()').criteria.script_fields).to include(distance: 'test()') }
|
110
|
+
specify { expect { subject.script_fields(distance: 'test()') }.not_to change { subject.criteria.script_fields } }
|
111
|
+
end
|
112
|
+
|
104
113
|
describe '#script_score' do
|
105
114
|
specify { expect(subject.script_score('23')).to be_a described_class }
|
106
115
|
specify { expect(subject.script_score('23')).not_to eq(subject) }
|
@@ -422,6 +431,10 @@ describe Chewy::Query do
|
|
422
431
|
specify { expect(subject.types([:product, :city]).types!(:country).criteria.types).to match_array(['country']) }
|
423
432
|
end
|
424
433
|
|
434
|
+
describe '#search_type' do
|
435
|
+
specify { expect(subject.search_type(:count).options).to include(search_type: :count) }
|
436
|
+
end
|
437
|
+
|
425
438
|
describe '#aggregations' do
|
426
439
|
specify { expect(subject.aggregations(attribute: {terms: {field: 'attribute'}})).to be_a described_class }
|
427
440
|
specify { expect(subject.aggregations(attribute: {terms: {field: 'attribute'}})).not_to eq(subject) }
|
data/spec/chewy/runtime_spec.rb
CHANGED
@@ -4,6 +4,6 @@ describe Chewy::Runtime do
|
|
4
4
|
describe '.version' do
|
5
5
|
specify { expect(described_class.version).to be_a(described_class::Version) }
|
6
6
|
specify { expect(described_class.version).to be >= '1.0' }
|
7
|
-
specify { expect(described_class.version).to be < '1.
|
7
|
+
specify { expect(described_class.version).to be < '1.6' }
|
8
8
|
end
|
9
9
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
if defined?(::Resque)
|
4
|
+
require 'resque_spec'
|
5
|
+
|
6
|
+
describe Chewy::Strategy::Resque do
|
7
|
+
around { |example| Chewy.strategy(:bypass) { example.run } }
|
8
|
+
before { ResqueSpec.reset! }
|
9
|
+
before do
|
10
|
+
stub_model(:city) do
|
11
|
+
update_index('cities#city') { self }
|
12
|
+
end
|
13
|
+
|
14
|
+
stub_index(:cities) do
|
15
|
+
define_type City
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:city) { City.create!(name: 'hello') }
|
20
|
+
let(:other_city) { City.create!(name: 'world') }
|
21
|
+
|
22
|
+
specify do
|
23
|
+
expect { [city, other_city].map(&:save!) }
|
24
|
+
.not_to update_index(CitiesIndex::City, strategy: :resque)
|
25
|
+
end
|
26
|
+
|
27
|
+
specify do
|
28
|
+
with_resque do
|
29
|
+
expect { [city, other_city].map(&:save!) }
|
30
|
+
.to update_index(CitiesIndex::City, strategy: :resque)
|
31
|
+
.and_reindex(city, other_city)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
if defined?(::Sidekiq)
|
4
|
+
require 'sidekiq/testing'
|
5
|
+
|
6
|
+
describe Chewy::Strategy::Sidekiq do
|
7
|
+
around { |example| Chewy.strategy(:bypass) { example.run } }
|
8
|
+
before { ::Sidekiq::Worker.clear_all }
|
9
|
+
before do
|
10
|
+
stub_model(:city) do
|
11
|
+
update_index('cities#city') { self }
|
12
|
+
end
|
13
|
+
|
14
|
+
stub_index(:cities) do
|
15
|
+
define_type City
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:city) { City.create!(name: 'hello') }
|
20
|
+
let(:other_city) { City.create!(name: 'world') }
|
21
|
+
|
22
|
+
specify do
|
23
|
+
expect { [city, other_city].map(&:save!) }
|
24
|
+
.not_to update_index(CitiesIndex::City, strategy: :sidekiq)
|
25
|
+
end
|
26
|
+
|
27
|
+
specify do
|
28
|
+
::Sidekiq::Testing.inline! do
|
29
|
+
expect { [city, other_city].map(&:save!) }
|
30
|
+
.to update_index(CitiesIndex::City, strategy: :sidekiq)
|
31
|
+
.and_reindex(city, other_city)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -41,10 +41,19 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
|
|
41
41
|
subject { described_class.new(City) }
|
42
42
|
let!(:cities) { 3.times.map { City.create! } }
|
43
43
|
|
44
|
-
specify { expect(subject.identify(City.all)).to match_array(cities.map(&:id)) }
|
45
|
-
specify { expect(subject.identify(cities)).to eq(cities.map(&:id)) }
|
46
|
-
specify { expect(subject.identify(cities.first)).to eq([cities.first.id]) }
|
47
|
-
specify { expect(subject.identify(cities.first(2).map(&:id))).to eq(cities.first(2).map(&:id)) }
|
44
|
+
specify { expect(subject.identify(City.all)).to match_array(cities.map(&:id).map(&:to_s)) }
|
45
|
+
specify { expect(subject.identify(cities)).to eq(cities.map(&:id).map(&:to_s)) }
|
46
|
+
specify { expect(subject.identify(cities.first)).to eq([cities.first.id.to_s]) }
|
47
|
+
specify { expect(subject.identify(cities.first(2).map(&:id))).to eq(cities.first(2).map(&:id).map(&:to_s)) }
|
48
|
+
|
49
|
+
context 'non-bson ids' do
|
50
|
+
let!(:cities) { 3.times.map { |i| City.create! id: i+1 } }
|
51
|
+
|
52
|
+
specify { expect(subject.identify(City.all)).to match_array(cities.map(&:id)) }
|
53
|
+
specify { expect(subject.identify(cities)).to eq(cities.map(&:id)) }
|
54
|
+
specify { expect(subject.identify(cities.first)).to eq([cities.first.id]) }
|
55
|
+
specify { expect(subject.identify(cities.first(2).map(&:id))).to eq(cities.first(2).map(&:id)) }
|
56
|
+
end
|
48
57
|
end
|
49
58
|
|
50
59
|
describe '#import' do
|
@@ -59,7 +68,7 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
|
|
59
68
|
let!(:deleted) { 4.times.map { |i| City.create!.tap(&:destroy) }.sort_by(&:id) }
|
60
69
|
subject { described_class.new(City) }
|
61
70
|
|
62
|
-
specify { expect(import).to
|
71
|
+
specify { expect(import).to match([{index: match_array(cities)}]) }
|
63
72
|
specify { expect(import nil).to eq([]) }
|
64
73
|
|
65
74
|
specify { expect(import(City.order(:id.asc))).to eq([{index: cities}]) }
|
@@ -145,8 +154,8 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
|
|
145
154
|
end
|
146
155
|
|
147
156
|
context 'default scope' do
|
148
|
-
let!(:cities) { 4.times.map { |i| City.create!(rating: i/3) }.sort_by(&:id) }
|
149
|
-
let!(:deleted) { 3.times.map { |i| City.create
|
157
|
+
let!(:cities) { 4.times.map { |i| City.create!(id: i, rating: i/3) }.sort_by(&:id) }
|
158
|
+
let!(:deleted) { 3.times.map { |i| City.create!(id: 4 + i).tap(&:destroy) }.sort_by(&:id) }
|
150
159
|
subject { described_class.new(City.where(rating: 0)) }
|
151
160
|
|
152
161
|
specify { expect(import).to eq([{index: cities.first(3)}]) }
|
@@ -242,8 +251,8 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
|
|
242
251
|
|
243
252
|
describe '#load' do
|
244
253
|
context do
|
245
|
-
let!(:cities) { 3.times.map { |i| City.create!(rating: i/2) }.sort_by(&:id) }
|
246
|
-
let!(:deleted) { 2.times.map { |i| City.create
|
254
|
+
let!(:cities) { 3.times.map { |i| City.create!(id: i, rating: i/2) }.sort_by(&:id) }
|
255
|
+
let!(:deleted) { 2.times.map { |i| City.create!(id: 3 + i).tap(&:destroy) }.sort_by(&:id) }
|
247
256
|
|
248
257
|
let(:type) { double(type_name: 'user') }
|
249
258
|
|