mongoid 5.0.1 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +2 -0
  5. data/README.md +0 -1
  6. data/lib/mongoid.rb +0 -7
  7. data/lib/mongoid/attributes.rb +2 -1
  8. data/lib/mongoid/attributes/nested.rb +3 -0
  9. data/lib/mongoid/clients.rb +0 -6
  10. data/lib/mongoid/clients/options.rb +0 -6
  11. data/lib/mongoid/clients/storage_options.rb +0 -3
  12. data/lib/mongoid/clients/thread_options.rb +0 -3
  13. data/lib/mongoid/config.rb +0 -7
  14. data/lib/mongoid/contextual/command.rb +0 -3
  15. data/lib/mongoid/contextual/mongo.rb +2 -2
  16. data/lib/mongoid/criteria.rb +6 -1
  17. data/lib/mongoid/extensions/hash.rb +1 -1
  18. data/lib/mongoid/indexable.rb +7 -5
  19. data/lib/mongoid/indexable/specification.rb +14 -0
  20. data/lib/mongoid/indexable/validators/options.rb +2 -1
  21. data/lib/mongoid/persistable/settable.rb +8 -1
  22. data/lib/mongoid/query_cache.rb +14 -4
  23. data/lib/mongoid/railtie.rb +1 -0
  24. data/lib/mongoid/relations/accessors.rb +3 -1
  25. data/lib/mongoid/relations/embedded/batchable.rb +5 -1
  26. data/lib/mongoid/relations/metadata.rb +3 -0
  27. data/lib/mongoid/tasks/database.rb +1 -1
  28. data/lib/mongoid/threaded.rb +0 -5
  29. data/lib/mongoid/version.rb +1 -1
  30. data/spec/app/models/bomb.rb +4 -0
  31. data/spec/app/models/building.rb +2 -1
  32. data/spec/app/models/building_address.rb +3 -1
  33. data/spec/app/models/courier_job.rb +4 -0
  34. data/spec/app/models/explosion.rb +4 -0
  35. data/spec/app/models/message.rb +3 -0
  36. data/spec/app/models/name.rb +1 -0
  37. data/spec/app/models/post.rb +3 -0
  38. data/spec/app/models/sandwich.rb +5 -0
  39. data/spec/app/models/shipment_address.rb +2 -0
  40. data/spec/mongoid/attributes/nested_spec.rb +77 -18
  41. data/spec/mongoid/attributes_spec.rb +13 -0
  42. data/spec/mongoid/criteria_spec.rb +52 -0
  43. data/spec/mongoid/document_spec.rb +37 -13
  44. data/spec/mongoid/indexable/specification_spec.rb +25 -0
  45. data/spec/mongoid/persistable_spec.rb +17 -0
  46. data/spec/mongoid/query_cache_spec.rb +51 -2
  47. data/spec/mongoid/relations/accessors_spec.rb +69 -0
  48. data/spec/mongoid/relations/embedded/many_spec.rb +63 -0
  49. data/spec/mongoid/relations/embedded/one_spec.rb +45 -0
  50. data/spec/mongoid/relations/metadata_spec.rb +16 -0
  51. data/spec/mongoid/relations/referenced/one_spec.rb +24 -0
  52. data/spec/mongoid/tasks/database_spec.rb +19 -0
  53. data/spec/spec_helper.rb +1 -8
  54. metadata +10 -2
  55. metadata.gz.sig +0 -0
@@ -47,7 +47,7 @@ module Mongoid
47
47
  # ignore default index
48
48
  unless index['name'] == '_id_'
49
49
  key = index['key'].symbolize_keys
50
- spec = model.index_specification(key)
50
+ spec = model.index_specification(key, index['name'])
51
51
  unless spec
52
52
  # index not specified
53
53
  undefined_by_model[model] ||= []
@@ -31,7 +31,6 @@ module Mongoid
31
31
  hash[key] = "[mongoid]:#{key}-stack"
32
32
  end
33
33
 
34
- extend Gem::Deprecate
35
34
  extend self
36
35
 
37
36
  # Begin entry into a named thread local stack.
@@ -175,8 +174,6 @@ module Mongoid
175
174
  def client_override
176
175
  Thread.current[CLIENT_OVERRIDE_KEY]
177
176
  end
178
- alias :session_override :client_override
179
- deprecate :session_override, :client_override, 2015, 12
180
177
 
181
178
  # Set the global client override.
182
179
  #
@@ -191,8 +188,6 @@ module Mongoid
191
188
  def client_override=(name)
192
189
  Thread.current[CLIENT_OVERRIDE_KEY] = name
193
190
  end
194
- alias :session_override= :client_override=
195
- deprecate :session_override=, :client_override=, 2015, 12
196
191
 
197
192
  # Get the current Mongoid scope.
198
193
  #
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid
3
- VERSION = "5.0.1"
3
+ VERSION = "5.0.2"
4
4
  end
@@ -0,0 +1,4 @@
1
+ class Bomb
2
+ include Mongoid::Document
3
+ has_one :explosion, dependent: :delete, autobuild: true
4
+ end
@@ -1,5 +1,6 @@
1
1
  class Building
2
2
  include Mongoid::Document
3
- embeds_one :building_address
3
+
4
+ embeds_one :building_address, validate: false
4
5
  embeds_many :contractors
5
6
  end
@@ -1,5 +1,7 @@
1
1
  class BuildingAddress
2
2
  include Mongoid::Document
3
- embedded_in :building
4
3
  field :city, type: String
4
+
5
+ embedded_in :building
6
+ validates_presence_of :city
5
7
  end
@@ -0,0 +1,4 @@
1
+ class CourierJob
2
+ include Mongoid::Document
3
+ embeds_one :drop_address, as: :addressable, autobuild: true, class_name: "ShipmentAddress"
4
+ end
@@ -0,0 +1,4 @@
1
+ class Explosion
2
+ include Mongoid::Document
3
+ belongs_to :bomb
4
+ end
@@ -2,7 +2,10 @@ class Message
2
2
  include Mongoid::Document
3
3
 
4
4
  field :body, type: String
5
+ field :priority, type: Integer
5
6
 
6
7
  embedded_in :person
7
8
  has_and_belongs_to_many :receviers, class_name: "Person", inverse_of: nil
9
+
10
+ has_one :post, as: :posteable
8
11
  end
@@ -14,6 +14,7 @@ class Name
14
14
  embeds_many :translations, validate: false
15
15
  embeds_one :language, as: :translatable, validate: false
16
16
  embedded_in :namable, polymorphic: true
17
+ embedded_in :person
17
18
 
18
19
  accepts_nested_attributes_for :language
19
20
 
@@ -15,6 +15,9 @@ class Post
15
15
  has_many :videos, validate: false
16
16
  has_many :roles, validate: false
17
17
 
18
+ belongs_to :posteable, polymorphic: true
19
+ accepts_nested_attributes_for :posteable, autosave: true
20
+
18
21
  scope :recent, ->{ where(created_at: { "$lt" => Time.now, "$gt" => 30.days.ago }) }
19
22
  scope :posting, ->{ where(:content.in => [ "Posting" ]) }
20
23
  scope :open, ->{ where(title: "open") }
@@ -1,4 +1,9 @@
1
1
  class Sandwich
2
2
  include Mongoid::Document
3
3
  has_and_belongs_to_many :meats
4
+
5
+ field :name, type: String
6
+
7
+ belongs_to :posteable, polymorphic: true
8
+ accepts_nested_attributes_for :posteable, autosave: true
4
9
  end
@@ -0,0 +1,2 @@
1
+ class ShipmentAddress < Address
2
+ end
@@ -102,6 +102,19 @@ describe Mongoid::Attributes::Nested do
102
102
  end
103
103
  end
104
104
 
105
+ context "when the association is referenced in and polymorphic" do
106
+
107
+ it "infers the class name of the polymorphic with the inverse type" do
108
+ expect {
109
+ Post.create!(
110
+ title: "Some title",
111
+ posteable_type: "Sandwich",
112
+ posteable_attributes: { name: 'Grilled Cheese' }
113
+ )
114
+ }.not_to raise_error
115
+ end
116
+ end
117
+
105
118
  context "when the relation is an embedded in" do
106
119
 
107
120
  before do
@@ -4788,38 +4801,84 @@ describe Mongoid::Attributes::Nested do
4788
4801
  league.divisions.create(name: "Old Name")
4789
4802
  end
4790
4803
 
4791
- let(:params) do
4792
- { divisions_attributes:
4793
- { "0" => { id: division.id.to_s, name: "New Name" }}
4794
- }
4795
- end
4804
+ context "when additional validation is set" do
4796
4805
 
4797
- before do
4798
- league.update_attributes(params)
4799
- end
4806
+ before do
4807
+ League.validates_presence_of(:divisions)
4808
+ end
4800
4809
 
4801
- it "sets the nested attributes" do
4802
- expect(league.reload.divisions.first.name).to eq("New Name")
4803
- end
4810
+ after do
4811
+ League.reset_callbacks(:validate)
4812
+ end
4804
4813
 
4805
- context "with corrupted data" do
4814
+ context "when validation fails" do
4806
4815
 
4807
- before do
4808
- league[:league] = params
4816
+ let(:division) do
4817
+ Division.new
4818
+ end
4819
+
4820
+ let(:league) do
4821
+ League.create!(divisions: [division])
4822
+ end
4823
+
4824
+ let(:error_raising_update) do
4825
+ league.update!(:divisions => nil)
4826
+ end
4827
+
4828
+ before do
4829
+ league.update(:divisions => nil)
4830
+ league.reload
4831
+ end
4832
+
4833
+ it "the update raises an error" do
4834
+ expect{ error_raising_update }.to raise_error
4835
+ end
4836
+
4837
+ it "the update does not occur" do
4838
+ expect(league.divisions.first).to eq(division)
4839
+ end
4840
+
4841
+ it "the document is inaccurately marked destroyed (you fixed the bug if you broke this!)" do
4842
+ expect(division).to be_destroyed
4843
+ end
4809
4844
  end
4845
+ end
4810
4846
 
4811
- let(:new_params) do
4847
+ context "when no additional validation is set" do
4848
+
4849
+ let(:params) do
4812
4850
  { divisions_attributes:
4813
- { "0" => { id: division.id.to_s, name: "Name" }}
4851
+ { "0" => { id: division.id.to_s, name: "New Name" }}
4814
4852
  }
4815
4853
  end
4816
4854
 
4817
4855
  before do
4818
- league.update_attributes(new_params)
4856
+ league.update_attributes(params)
4819
4857
  end
4820
4858
 
4821
4859
  it "sets the nested attributes" do
4822
- expect(league.reload.divisions.first.name).to eq("Name")
4860
+ expect(league.reload.divisions.first.name).to eq("New Name")
4861
+ end
4862
+
4863
+ context "with corrupted data" do
4864
+
4865
+ before do
4866
+ league[:league] = params
4867
+ end
4868
+
4869
+ let(:new_params) do
4870
+ { divisions_attributes:
4871
+ { "0" => { id: division.id.to_s, name: "Name" }}
4872
+ }
4873
+ end
4874
+
4875
+ before do
4876
+ league.update_attributes(new_params)
4877
+ end
4878
+
4879
+ it "sets the nested attributes" do
4880
+ expect(league.reload.divisions.first.name).to eq("Name")
4881
+ end
4823
4882
  end
4824
4883
  end
4825
4884
  end
@@ -1207,6 +1207,19 @@ describe Mongoid::Attributes do
1207
1207
  }.to raise_error(Mongoid::Errors::InvalidValue)
1208
1208
  end
1209
1209
  end
1210
+
1211
+ context "when attribute is localized and #attributes is a BSON::Document" do
1212
+ let(:dictionary) { Dictionary.new }
1213
+
1214
+ before do
1215
+ allow(dictionary).to receive(:attributes).and_return(BSON::Document.new)
1216
+ end
1217
+
1218
+ it "sets the value for the current locale" do
1219
+ dictionary.write_attribute(:description, 'foo')
1220
+ expect(dictionary.description).to eq('foo')
1221
+ end
1222
+ end
1210
1223
  end
1211
1224
 
1212
1225
  describe "#typed_value_for" do
@@ -3254,6 +3254,25 @@ describe Mongoid::Criteria do
3254
3254
  expect(criteria.selector).to eq({ "agent_ids" => [ id_one, id_two ]})
3255
3255
  end
3256
3256
  end
3257
+
3258
+ context "when querying on a big decimal" do
3259
+
3260
+ let(:sales) do
3261
+ BigDecimal.new('0.1')
3262
+ end
3263
+
3264
+ let!(:band) do
3265
+ Band.create(name: "Boards of Canada", sales: sales)
3266
+ end
3267
+
3268
+ let(:from_db) do
3269
+ Band.where(sales: sales).first
3270
+ end
3271
+
3272
+ it "finds the document by the big decimal value" do
3273
+ expect(from_db).to eq(band)
3274
+ end
3275
+ end
3257
3276
  end
3258
3277
  end
3259
3278
 
@@ -3468,4 +3487,37 @@ describe Mongoid::Criteria do
3468
3487
  end
3469
3488
  end
3470
3489
  end
3490
+
3491
+ describe "#type_selection" do
3492
+
3493
+ context "when only one subclass exists" do
3494
+
3495
+ let(:criteria) do
3496
+ described_class.new(Firefox)
3497
+ end
3498
+
3499
+ let(:selection) do
3500
+ criteria.send(:type_selection)
3501
+ end
3502
+
3503
+ it "does not use an $in query" do
3504
+ expect(selection).to eq({ _type: "Firefox" })
3505
+ end
3506
+ end
3507
+
3508
+ context "when more than one subclass exists" do
3509
+
3510
+ let(:criteria) do
3511
+ described_class.new(Browser)
3512
+ end
3513
+
3514
+ let(:selection) do
3515
+ criteria.send(:type_selection)
3516
+ end
3517
+
3518
+ it "does not use an $in query" do
3519
+ expect(selection).to eq({ _type: { "$in" => [ "Firefox", "Browser" ]}})
3520
+ end
3521
+ end
3522
+ end
3471
3523
  end
@@ -613,25 +613,49 @@ describe Mongoid::Document do
613
613
  Person.new
614
614
  end
615
615
 
616
- context "when not frozen" do
616
+ context "when freezing the model" do
617
617
 
618
- it "freezes attributes" do
619
- expect(person.freeze).to eq(person)
620
- expect { person.title = "something" }.to raise_error
618
+ context "when not frozen" do
619
+
620
+ it "freezes attributes" do
621
+ expect(person.freeze).to eq(person)
622
+ expect { person.title = "something" }.to raise_error
623
+ end
621
624
  end
622
- end
623
625
 
624
- context "when frozen" do
626
+ context "when frozen" do
625
627
 
626
- before do
627
- person.raw_attributes.freeze
628
+ before do
629
+ person.raw_attributes.freeze
630
+ end
631
+
632
+ it "keeps things frozen" do
633
+ person.freeze
634
+ expect {
635
+ person.title = "something"
636
+ }.to raise_error
637
+ end
628
638
  end
639
+ end
629
640
 
630
- it "keeps things frozen" do
631
- person.freeze
632
- expect {
633
- person.title = "something"
634
- }.to raise_error
641
+ context "when freezing attributes of the model" do
642
+
643
+ context "when assigning a frozen value" do
644
+
645
+ context "when the frozen value is a hash" do
646
+
647
+ let(:hash) do
648
+ {"foo" => {"bar" => {"baz" => [1,2,3]}}}
649
+ end
650
+
651
+ let(:assign_hash) do
652
+ person.map = hash.freeze
653
+ end
654
+
655
+ it "no mutation occurs during assignment" do
656
+ expect{ assign_hash }.not_to raise_error
657
+ end
658
+ end
635
659
  end
636
660
  end
637
661
  end
@@ -99,4 +99,29 @@ describe Mongoid::Indexable::Specification do
99
99
  expect(spec.options).to eq(background: true, drop_dups: true)
100
100
  end
101
101
  end
102
+
103
+ describe '#name' do
104
+
105
+ context 'when there is only one field' do
106
+
107
+ let(:spec) do
108
+ described_class.new(Band, { name: 1 })
109
+ end
110
+
111
+ it 'returns the key and direction separated by an underscore' do
112
+ expect(spec.name).to eq('name_1')
113
+ end
114
+ end
115
+
116
+ context 'when there are two fields' do
117
+
118
+ let(:spec) do
119
+ described_class.new(Band, { name: 1, title: -1 })
120
+ end
121
+
122
+ it 'returns the keys and directions separated by underscores' do
123
+ expect(spec.name).to eq('name_1_title_-1')
124
+ end
125
+ end
126
+ end
102
127
  end
@@ -203,4 +203,21 @@ describe Mongoid::Persistable do
203
203
  }.to raise_error(Mongoid::Errors::Callback)
204
204
  end
205
205
  end
206
+
207
+ example "able use set value using dot notation" do
208
+ class Customer
209
+ include Mongoid::Document
210
+
211
+ field :address, type: Hash, default: -> {{}}
212
+ end
213
+
214
+ customer = Customer.new
215
+ customer.save
216
+ customer.set 'address.country' => 'India'
217
+ expect(customer.address).to eql({ 'country' => 'India' })
218
+ customer.set 'address.country.state' => 'MH'
219
+ expect(customer.address).to eql({'country' => { 'state' => 'MH' }})
220
+ customer.set 'address' => { 'country' => 'India'}
221
+ expect(customer.address).to eql({ 'country' => 'India' })
222
+ end
206
223
  end