mongoid_paranoia 0.1.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.
@@ -0,0 +1,71 @@
1
+ class Address
2
+ include Mongoid::Document
3
+
4
+ field :_id, type: String, default: ->{ street.try(:parameterize) }
5
+
6
+ attr_accessor :mode
7
+
8
+ field :address_type
9
+ field :number, type: Integer
10
+ field :street
11
+ field :city
12
+ field :state
13
+ field :post_code
14
+ field :parent_title
15
+ field :services, type: Array
16
+ field :latlng, type: Array
17
+ field :map, type: Hash
18
+ field :move_in, type: DateTime
19
+ field :s, type: String, as: :suite
20
+ field :name, localize: true
21
+
22
+ embeds_one :code, validate: false
23
+ embeds_one :target, as: :targetable, validate: false
24
+
25
+ embedded_in :addressable, polymorphic: true do
26
+ def extension
27
+ "Testing"
28
+ end
29
+ def doctor?
30
+ title == "Dr"
31
+ end
32
+ end
33
+
34
+ accepts_nested_attributes_for :code, :target
35
+
36
+ belongs_to :account
37
+
38
+ scope :without_postcode, -> {where(postcode: nil)}
39
+ scope :rodeo, -> {
40
+ where(street: "Rodeo Dr") do
41
+ def mansion?
42
+ all? { |address| address.street == "Rodeo Dr" }
43
+ end
44
+ end
45
+ }
46
+
47
+ validates_presence_of :street, on: :update
48
+ validates_format_of :street, with: /\D/, allow_nil: true
49
+
50
+ def set_parent=(set = false)
51
+ self.parent_title = addressable.title if set
52
+ end
53
+
54
+ def <=>(other)
55
+ street <=> other.street
56
+ end
57
+
58
+ class << self
59
+ def california
60
+ where(state: "CA")
61
+ end
62
+
63
+ def homes
64
+ where(address_type: "Home")
65
+ end
66
+
67
+ def streets
68
+ all.map(&:street)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,7 @@
1
+ class Appointment
2
+ include Mongoid::Document
3
+ field :active, type: Boolean, default: true
4
+ field :timed, type: Boolean, default: true
5
+ embedded_in :person
6
+ default_scope ->{where(active: true)}
7
+ end
@@ -0,0 +1,6 @@
1
+ class Author
2
+ include Mongoid::Document
3
+ field :name, type: String
4
+
5
+ belongs_to :post, class_name: "ParanoidPost"
6
+ end
@@ -0,0 +1,8 @@
1
+ class Fish
2
+ include Mongoid::Document
3
+ include Mongoid::Paranoia
4
+
5
+ def self.fresh
6
+ where(fresh: true)
7
+ end
8
+ end
@@ -0,0 +1,25 @@
1
+ class ParanoidPhone
2
+ include Mongoid::Document
3
+ include Mongoid::Paranoia
4
+
5
+ attr_accessor :after_destroy_called, :before_destroy_called
6
+
7
+ field :number, type: String
8
+
9
+ embedded_in :person
10
+
11
+ before_destroy :before_destroy_stub, :halt_me
12
+ after_destroy :after_destroy_stub
13
+
14
+ def before_destroy_stub
15
+ self.before_destroy_called = true
16
+ end
17
+
18
+ def after_destroy_stub
19
+ self.after_destroy_called = true
20
+ end
21
+
22
+ def halt_me
23
+ person.age == 42 ? false : true
24
+ end
25
+ end
@@ -0,0 +1,53 @@
1
+ class ParanoidPost
2
+ include Mongoid::Document
3
+ include Mongoid::Paranoia
4
+
5
+ field :title, type: String
6
+
7
+ attr_accessor :after_destroy_called, :before_destroy_called,
8
+ :after_restore_called, :before_restore_called,
9
+ :around_before_restore_called, :around_after_restore_called
10
+
11
+ belongs_to :person
12
+
13
+ has_and_belongs_to_many :tags
14
+ has_many :authors, dependent: :delete, inverse_of: :post
15
+ has_many :titles, dependent: :restrict
16
+
17
+ scope :recent, -> {where(created_at: { "$lt" => Time.now, "$gt" => 30.days.ago })}
18
+
19
+ before_destroy :before_destroy_stub
20
+ after_destroy :after_destroy_stub
21
+
22
+ before_restore :before_restore_stub
23
+ after_restore :after_restore_stub
24
+ around_restore :around_restore_stub
25
+
26
+ def before_destroy_stub
27
+ self.before_destroy_called = true
28
+ end
29
+
30
+ def after_destroy_stub
31
+ self.after_destroy_called = true
32
+ end
33
+
34
+ def before_restore_stub
35
+ self.before_restore_called = true
36
+ end
37
+
38
+ def after_restore_stub
39
+ self.after_restore_called = true
40
+ end
41
+
42
+ def around_restore_stub
43
+ self.around_before_restore_called = true
44
+ yield
45
+ self.around_after_restore_called = true
46
+ end
47
+
48
+ class << self
49
+ def old
50
+ where(created_at: { "$lt" => 30.days.ago })
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,190 @@
1
+ class Person
2
+ include Mongoid::Document
3
+ attr_accessor :mode
4
+
5
+ class_attribute :somebody_elses_important_class_options
6
+ self.somebody_elses_important_class_options = { keep_me_around: true }
7
+
8
+ field :title
9
+ field :terms, type: Boolean
10
+ field :pets, type: Boolean, default: false
11
+ field :age, type: Integer, default: "100"
12
+ field :dob, type: Date
13
+ field :employer_id
14
+ field :lunch_time, type: Time
15
+ field :aliases, type: Array
16
+ field :map, type: Hash
17
+ field :map_with_default, type: Hash, default: {}
18
+ field :score, type: Integer
19
+ field :blood_alcohol_content, type: Float, default: ->{ 0.0 }
20
+ field :last_drink_taken_at, type: Date
21
+ field :ssn
22
+ field :owner_id, type: Integer
23
+ field :security_code
24
+ field :reading, type: Object
25
+ field :bson_id, type: BSON::ObjectId
26
+ field :pattern, type: Regexp
27
+ field :override_me, type: Integer
28
+ field :t, as: :test, type: String
29
+ field :i, as: :inte, type: Integer
30
+ field :a, as: :array, type: Array
31
+ field :desc, localize: true
32
+
33
+ index age: 1
34
+ index addresses: 1
35
+ index dob: 1
36
+ index name: 1
37
+ index title: 1
38
+
39
+ index({ ssn: 1 }, { unique: true })
40
+
41
+ attr_reader :rescored
42
+
43
+ embeds_many :phone_numbers, class_name: "Phone", validate: false
44
+ embeds_many :phones, store_as: :mobile_phones, validate: false
45
+ embeds_many :addresses, as: :addressable, validate: false do
46
+ def extension
47
+ "Testing"
48
+ end
49
+ def find_by_street(street)
50
+ where(street: street).first
51
+ end
52
+ end
53
+
54
+ embeds_many :appointments, validate: false
55
+ embeds_many :paranoid_phones, validate: false
56
+
57
+ embeds_one :passport, autobuild: true, store_as: :pass, validate: false
58
+ embeds_one :pet, class_name: "Animal", validate: false
59
+ embeds_one :name, as: :namable, validate: false do
60
+ def extension
61
+ "Testing"
62
+ end
63
+ def dawkins?
64
+ first_name == "Richard" && last_name == "Dawkins"
65
+ end
66
+ end
67
+ embeds_one :quiz, validate: false
68
+
69
+ has_one :game, dependent: :destroy, validate: false do
70
+ def extension
71
+ "Testing"
72
+ end
73
+ end
74
+
75
+ has_many \
76
+ :posts,
77
+ dependent: :delete,
78
+ validate: false do
79
+ def extension
80
+ "Testing"
81
+ end
82
+ end
83
+ has_many :ordered_posts, order: :rating.desc, validate: false
84
+ has_and_belongs_to_many \
85
+ :preferences,
86
+ index: true,
87
+ dependent: :nullify,
88
+ validate: false
89
+ has_and_belongs_to_many :user_accounts, validate: false
90
+ has_and_belongs_to_many :houses, validate: false
91
+ has_and_belongs_to_many :ordered_preferences, order: :value.desc, validate: false
92
+
93
+ has_many :drugs, validate: false
94
+ has_many :paranoid_posts, validate: false
95
+ has_one :account, validate: false
96
+ has_one :cat, dependent: :nullify, validate: false
97
+ has_one :book, autobuild: true, validate: false
98
+ has_one :home, dependent: :delete, validate: false
99
+
100
+ belongs_to :paranoid_post
101
+
102
+ has_and_belongs_to_many \
103
+ :administrated_events,
104
+ class_name: 'Event',
105
+ inverse_of: :administrators,
106
+ dependent: :nullify,
107
+ validate: false
108
+
109
+ accepts_nested_attributes_for :addresses
110
+ accepts_nested_attributes_for :name, update_only: true
111
+ accepts_nested_attributes_for :pet, allow_destroy: true
112
+ accepts_nested_attributes_for :game, allow_destroy: true
113
+ accepts_nested_attributes_for :posts
114
+ accepts_nested_attributes_for :preferences
115
+ accepts_nested_attributes_for :quiz
116
+ accepts_nested_attributes_for :paranoid_phones
117
+
118
+ scope :minor, ->{where(:age.lt => 18)}
119
+ scope :without_ssn, ->{without(:ssn)}
120
+ scope :search, ->(query){ any_of({ title: query }) }
121
+
122
+ def score_with_rescoring=(score)
123
+ @rescored = score.to_i + 20
124
+ self.score_without_rescoring = score
125
+ end
126
+
127
+ alias_method_chain :score=, :rescoring
128
+
129
+ def update_addresses
130
+ addresses.each do |address|
131
+ address.street = "Updated Address"
132
+ end
133
+ end
134
+
135
+ def employer=(emp)
136
+ self.employer_id = emp.id
137
+ end
138
+
139
+ def set_addresses=(addresses)
140
+ self.addresses = addresses
141
+ end
142
+
143
+ def override_me
144
+ read_attribute(:override_me).to_s
145
+ end
146
+
147
+ class << self
148
+ def accepted
149
+ scoped.where(terms: true)
150
+ end
151
+ def knight
152
+ scoped.where(title: "Sir")
153
+ end
154
+ def old
155
+ scoped.where(age: { "$gt" => 50 })
156
+ end
157
+ end
158
+
159
+ def reject_if_city_is_empty(attrs)
160
+ attrs[:city].blank?
161
+ end
162
+
163
+ def reject_if_name_is_blank(attrs)
164
+ attrs[:first_name].blank?
165
+ end
166
+
167
+ def foo
168
+ 'i_am_foo'
169
+ end
170
+
171
+ def preference_names=(names)
172
+ names.split(",").each do |name|
173
+ preference = Preference.where(name: name).first
174
+ if preference
175
+ self.preferences << preference
176
+ else
177
+ preferences.build(name: name)
178
+ end
179
+ end
180
+ end
181
+
182
+ def set_on_map_with_default=(value)
183
+ self.map_with_default["key"] = value
184
+ end
185
+
186
+ reset_callbacks(:validate)
187
+ reset_callbacks(:create)
188
+ reset_callbacks(:save)
189
+ reset_callbacks(:destroy)
190
+ end
@@ -0,0 +1,11 @@
1
+ class Phone
2
+ include Mongoid::Document
3
+
4
+ attr_accessor :number_in_observer
5
+
6
+ field :_id, type: String, default: ->{ number }
7
+
8
+ field :number
9
+ embeds_one :country_code
10
+ embedded_in :person
11
+ end
@@ -0,0 +1,6 @@
1
+ class Tag
2
+ include Mongoid::Document
3
+ field :text, type: String
4
+ has_and_belongs_to_many :paranoid_posts
5
+ has_and_belongs_to_many :related, class_name: "Tag", inverse_of: :related
6
+ end
@@ -0,0 +1,4 @@
1
+ class Title
2
+ include Mongoid::Document
3
+ belongs_to :paranoid_post
4
+ end
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Document do
4
+
5
+ describe ".paranoid?" do
6
+
7
+ context "when Mongoid::Paranoia is included" do
8
+ subject { ParanoidPost }
9
+ it "returns true" do
10
+ expect(subject.paranoid?).to be_truthy
11
+ end
12
+ end
13
+
14
+ context "when Mongoid::Paranoia not included" do
15
+ subject { Author }
16
+ it "returns true" do
17
+ expect(subject.paranoid?).to be_falsey
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,164 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Attributes::Nested do
4
+ describe "##{name}_attributes=" do
5
+ context "when the parent document is new" do
6
+ context "when the relation is an embeds many" do
7
+ context "when ids are passed" do
8
+
9
+ let(:person) do
10
+ Person.create
11
+ end
12
+
13
+ let(:address_one) do
14
+ Address.new(street: "Unter den Linden")
15
+ end
16
+
17
+ let(:address_two) do
18
+ Address.new(street: "Kurfeurstendamm")
19
+ end
20
+
21
+ let(:phone_one) do
22
+ ParanoidPhone.new(number: "1")
23
+ end
24
+
25
+ let(:phone_two) do
26
+ ParanoidPhone.new(number: "2")
27
+ end
28
+
29
+ before do
30
+ person.addresses << [ address_one, address_two ]
31
+ end
32
+
33
+ context "when destroy attributes are passed" do
34
+ context "when the ids match" do
35
+ context "when allow_destroy is true" do
36
+ context "when the child is paranoid" do
37
+
38
+ before(:all) do
39
+ Person.send(:undef_method, :paranoid_phones_attributes=)
40
+ Person.accepts_nested_attributes_for :paranoid_phones,
41
+ allow_destroy: true
42
+ end
43
+
44
+ after(:all) do
45
+ Person.send(:undef_method, :paranoid_phones_attributes=)
46
+ Person.accepts_nested_attributes_for :paranoid_phones
47
+ end
48
+
49
+ [ 1, "1", true, "true" ].each do |truth|
50
+
51
+ context "when passed a #{truth} with destroy" do
52
+ context "when the parent is persisted" do
53
+
54
+ let!(:persisted) do
55
+ Person.create do |p|
56
+ p.paranoid_phones << [ phone_one, phone_two ]
57
+ end
58
+ end
59
+
60
+ context "when setting, pulling, and pushing in one op" do
61
+
62
+ before do
63
+ persisted.paranoid_phones_attributes =
64
+ {
65
+ "bar" => { "id" => phone_one.id, "_destroy" => truth },
66
+ "foo" => { "id" => phone_two.id, "number" => "3" },
67
+ "baz" => { "number" => "4" }
68
+ }
69
+ end
70
+
71
+ it "removes the first document from the relation" do
72
+ expect(persisted.paranoid_phones.size).to eq(2)
73
+ end
74
+
75
+ it "does not delete the unmarked document" do
76
+ expect(persisted.paranoid_phones.first.number).to eq("3")
77
+ end
78
+
79
+ it "adds the new document to the relation" do
80
+ expect(persisted.paranoid_phones.last.number).to eq("4")
81
+ end
82
+
83
+ it "has the proper persisted count" do
84
+ expect(persisted.paranoid_phones.count).to eq(1)
85
+ end
86
+
87
+ it "soft deletes the removed document" do
88
+ expect(phone_one).to be_destroyed
89
+ end
90
+
91
+ context "when saving the parent" do
92
+
93
+ before do
94
+ persisted.with(safe: true).save
95
+ end
96
+
97
+ it "deletes the marked document from the relation" do
98
+ expect(persisted.reload.paranoid_phones.count).to eq(2)
99
+ end
100
+
101
+ it "does not delete the unmarked document" do
102
+ expect(persisted.reload.paranoid_phones.first.number).to eq("3")
103
+ end
104
+
105
+ it "persists the new document to the relation" do
106
+ expect(persisted.reload.paranoid_phones.last.number).to eq("4")
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ context "when the child has defaults" do
116
+
117
+ before(:all) do
118
+ Person.accepts_nested_attributes_for :appointments, allow_destroy: true
119
+ end
120
+
121
+ after(:all) do
122
+ Person.send(:undef_method, :appointments_attributes=)
123
+ end
124
+ context "when the parent is persisted" do
125
+ context "when the child returns false in a before callback" do
126
+ context "when the child is paranoid" do
127
+
128
+ before(:all) do
129
+ Person.accepts_nested_attributes_for :paranoid_phones, allow_destroy: true
130
+ end
131
+
132
+ after(:all) do
133
+ Person.send(:undef_method, :paranoid_phones=)
134
+ Person.accepts_nested_attributes_for :paranoid_phones
135
+ end
136
+
137
+ let!(:persisted) do
138
+ Person.create(age: 42)
139
+ end
140
+
141
+ let!(:phone) do
142
+ persisted.paranoid_phones.create
143
+ end
144
+
145
+ before do
146
+ persisted.paranoid_phones_attributes =
147
+ { "foo" => { "id" => phone.id, "number" => 42, "_destroy" => true }}
148
+ end
149
+
150
+ it "does not destroy the child" do
151
+ expect(persisted.reload.paranoid_phones).not_to be_empty
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end