active_model_persistence 0.4.0 → 0.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d34c4046feea446188de7f1381ed024799bd8e545a50d9abf1e22f06ee0e06ee
4
- data.tar.gz: 585c06a05af51efb5123efb0c98b618f9747955f9040852ea08835c6f962fdc6
3
+ metadata.gz: e3b8a31cdacf32baeaabb6d3c72631002098c9a35630d1c0aff5e836737e42dc
4
+ data.tar.gz: '00843ca11ad71c596c192d066efc3f43d7e531c068d12bea9866f58bea404b3e'
5
5
  SHA512:
6
- metadata.gz: 846582f45f58f215e20ba67fb843898d3091c1af816d851689027d94c71c9973d4b5fc3d3b2798d4fd875a22d5a2fc7a5c2c3150f465cdd4aa29fee11e964f2c
7
- data.tar.gz: 0ad54fb60bae3d74fceacb8aa94a860bbb399219ccd791ef2376e56b794ec52e706c01eb91bb0e1ff4fb4d4d93af6f72c187d591f657f176ba69f84f15dfa387
6
+ metadata.gz: 25984dd367fedae9ead6973601c042a164643e5aaa09e5198ebcc6a8f5dfe333eba73d37f34ca257f61a58f6aca7b6b9326727f337b2d159d5d0bd71db62e0bd
7
+ data.tar.gz: ca0ddf06112d7e70bb7898f8f3ba0a95f63f5db4f9cf3aee1f6a7d054b3fd5dfb705609844d42ff55d9eab05a7652fb6f2fa086ca8d1a7a97b79e61ee6811cfe
data/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@
7
7
 
8
8
  The full change log is stored on [this project's GitHub releases page](https://github.com/jcouball/active_model_persistence/releases).
9
9
 
10
+ ## v0.5.0
11
+
12
+ * 87b32e5 Fix the version file after the previous revert (#20)
13
+ * f4f6c39 Revert "Add inheritance support (#14)" (#19)
14
+
15
+ See https://github.com/ruby-git/ruby-git/releases/tag/v0.5.0
16
+
10
17
  ## v0.4.0
11
18
 
12
19
  * e491e22 Set the version file back to the correct version (#17)
data/README.md CHANGED
@@ -65,82 +65,6 @@ Employee.find_by_manager_id('boss') #=> [e1, e2]
65
65
  # etc.
66
66
  ```
67
67
 
68
- ## Inheritance
69
-
70
- ActiveModelPersistence supports inheritance in models. Include
71
- `ActiveModelPersistence::Persistence` only in the base class.
72
-
73
- Here is an example with a `User` base class and two derived clases `Employee` and `Member`.
74
- Each derived class adds different attributes and indexes.
75
-
76
- ```ruby
77
- require 'active_model_persistence'
78
-
79
- class User
80
- include ActiveModelPersistence::Persistence
81
-
82
- attribute :id, :integer
83
- attribute :name, :string
84
- end
85
-
86
- class Employee < User
87
- attribute :manager_id, :integer
88
-
89
- index :manager_id, unique: false
90
- end
91
-
92
- class Member < User
93
- attribute :joined_on, :date, default: Date.today
94
-
95
- index :joined_on, unique: false
96
- end
97
- ```
98
-
99
- As an example, say we have one instance of each class:
100
-
101
- ```ruby
102
- user = User.create!(id: 1, name: 'User James')
103
- employee = Employee.create!(id: 2, name: 'Employee Bob', manager_id: nil)
104
- member = Member.create!(id: 3, name: 'Member Mary', joined_on: Date.parse('2022-01-01'))
105
- ```
106
-
107
- The primary key is shared by all objects of these classes so it must be unique for
108
- all objects created from these classes. For instance:
109
-
110
- ```ruby
111
- require 'rspec-expectations'
112
- include RSpec::Matchers
113
-
114
- # Creating a Member with the same primary key as a User will fail
115
- expect { Member.create!(id: 1, name: 'Member Jason') }.to(
116
- raise_error(ActiveModelPersistence::UniqueConstraintError)
117
- )
118
- ```
119
-
120
- Calling a find method such as `find` or `find_by_*` on a class will only return
121
- objects that are a kind of that class.
122
-
123
- That means calling a find method on `User` will return users, employees, or members:
124
-
125
- ```ruby
126
- expect(User.find(1)).to eq(user)
127
- expect(User.find(2)).to eq(employee)
128
- expect(User.find(3)).to eq(member)
129
- ```
130
-
131
- While calling a find method on `Employee` will only return employees:
132
-
133
- ```ruby
134
- expect(Employee.find(1)).to be_nil
135
- expect(Employee.find(2)).to eq(employee)
136
- expect(Employee.find(3)).to be_nil
137
- ```
138
-
139
- `all`, `count`, `delete_all`, `destroy_all` and other methods similarly limit what
140
- objects are acted upon based on what class they are called on.
141
-
142
- ## API Documentation
143
-
144
68
  See [the full API documentation](https://jcouball.github.io/active_record_persistence/) for more details.
145
69
 
146
70
  ## Installation
@@ -15,18 +15,6 @@ module ActiveModelPersistence
15
15
  #
16
16
  attr_reader :name
17
17
 
18
- # Identifies the base class this index applies to
19
- #
20
- # Objects that are not of this class or one of its subclasses will not be added to the index.
21
- #
22
- # @example
23
- # i = Index.new(name: 'id', base_class: self, key_source: :id, unique: true)
24
- # i.base_class == self #=> true
25
- #
26
- # @return [Class] the class this index applies to
27
- #
28
- attr_reader :base_class
29
-
30
18
  # Defines how the object's key value is calculated
31
19
  #
32
20
  # If a proc is provided, it will be called with the object as an argument to get the key value.
@@ -34,7 +22,7 @@ module ActiveModelPersistence
34
22
  # If a symbol is provided, it will identify the method to call on the object to get the key value.
35
23
  #
36
24
  # @example
37
- # i = Index.new(name: 'id', base_class: self, key_value_source: :id, unique: true)
25
+ # i = Index.new(name: 'id', key_value_source: :id, unique: true)
38
26
  # i.key_value_source # => :id
39
27
  #
40
28
  # @return [Symbol, Proc] the method name or proc used to calculate the index key
@@ -49,7 +37,7 @@ module ActiveModelPersistence
49
37
  # when trying to add the second object.
50
38
  #
51
39
  # @example
52
- # i = Index.new(name: 'id', base_class: self, key_value_source: :id, unique: true)
40
+ # i = Index.new(name: 'id', key_value_source: :id, unique: true)
53
41
  # i.unique? # => true
54
42
  #
55
43
  # @return [Boolean] true if the index is unique
@@ -86,9 +74,8 @@ module ActiveModelPersistence
86
74
  # @param key_value_source [Symbol, Proc] the attribute name or proc used to calculate the index key
87
75
  # @param unique [Boolean] when true the index will only allow one object per key
88
76
  #
89
- def initialize(name:, base_class:, key_value_source: nil, unique: false)
77
+ def initialize(name:, key_value_source: nil, unique: false)
90
78
  @name = name.to_s
91
- @base_class = base_class
92
79
  @key_value_source = determine_key_value_source(name, key_value_source)
93
80
  @unique = unique
94
81
  @key_to_objects_map = {}
@@ -241,7 +228,7 @@ module ActiveModelPersistence
241
228
  # @api private
242
229
  #
243
230
  def remove_object_from_index(object, key)
244
- key_to_objects_map[key].delete_if { |o| o.primary_key_value == object.primary_key_value }
231
+ key_to_objects_map[key].delete_if { |o| o.primary_key == object.primary_key }
245
232
  key_to_objects_map.delete(key) if key_to_objects_map[key].empty?
246
233
  object.clear_index_key(name)
247
234
  end
@@ -60,7 +60,6 @@ module ActiveModelPersistence
60
60
  # make these class methods on that class.
61
61
  #
62
62
  module ClassMethods
63
- # @!attribute [r] indexes
64
63
  # Returns a hash of indexes for the model keyed by name
65
64
  #
66
65
  # @example
@@ -68,7 +67,9 @@ module ActiveModelPersistence
68
67
  #
69
68
  # @return [Hash<String, ActiveModelPersistence::Index>] the indexes defined by the model
70
69
  #
71
- # @api public
70
+ def indexes
71
+ @indexes ||= {}
72
+ end
72
73
 
73
74
  # Adds an index to the model
74
75
  #
@@ -97,7 +98,9 @@ module ActiveModelPersistence
97
98
  indexes[index_name.to_sym] = index
98
99
 
99
100
  singleton_class.define_method("find_by_#{index_name}") do |key|
100
- index.objects(key).select { |object| object.is_a?(self) }
101
+ index.objects(key).tap do |objects|
102
+ objects.each { |o| o.instance_variable_set(:@previously_new_record, false) }
103
+ end
101
104
  end
102
105
  end
103
106
 
@@ -122,9 +125,7 @@ module ActiveModelPersistence
122
125
  # @return [void]
123
126
  #
124
127
  def update_indexes(object)
125
- indexes.each_value do |index|
126
- index.add_or_update(object) if object.is_a?(index.base_class)
127
- end
128
+ indexes.each_value { |index| index.add_or_update(object) }
128
129
  end
129
130
 
130
131
  # Removes the given object from all defined indexes
@@ -143,9 +144,7 @@ module ActiveModelPersistence
143
144
  # @return [void]
144
145
  #
145
146
  def remove_from_indexes(object)
146
- indexes.each_value do |index|
147
- index.remove(object) if object.is_a?(index.base_class)
148
- end
147
+ indexes.each_value { |index| index.remove(object) }
149
148
  end
150
149
 
151
150
  private
@@ -159,15 +158,12 @@ module ActiveModelPersistence
159
158
  def default_index_options(index_name)
160
159
  {
161
160
  name: index_name.to_sym,
162
- base_class: self,
163
161
  unique: false
164
162
  }
165
163
  end
166
164
  end
167
165
 
168
166
  included do
169
- cattr_reader :indexes, instance_accessor: false, default: {}
170
-
171
167
  # Adds the object to the indexes defined by the model
172
168
  #
173
169
  # @example
@@ -158,7 +158,7 @@ module ActiveModelPersistence
158
158
  # @return [Array<Object>] the model objects in the object store
159
159
  #
160
160
  def all
161
- object_array.select { |object| object.is_a?(self) }.each
161
+ object_array.each
162
162
  end
163
163
 
164
164
  # The number of model objects saved in the object store
@@ -174,7 +174,7 @@ module ActiveModelPersistence
174
174
  # @return [Integer] the number of model objects in the object store
175
175
  #
176
176
  def count
177
- object_array.select { |object| object.is_a?(self) }.size
177
+ object_array.size
178
178
  end
179
179
 
180
180
  alias size count
@@ -196,11 +196,30 @@ module ActiveModelPersistence
196
196
  # @return [void]
197
197
  #
198
198
  def destroy_all
199
- objects_to_destroy = object_array.select { |object| object.is_a?(self) }
200
- objects_to_destroy.each(&:destroy)
199
+ object_array.first.destroy while object_array.size.positive?
201
200
  end
202
201
 
203
- alias delete_all destroy_all
202
+ # Removes all model objects from the object store
203
+ #
204
+ # Each saved model object's `#destroy` method is NOT called.
205
+ #
206
+ # @example
207
+ # array_of_attributes = [
208
+ # { id: 1, name: 'James' },
209
+ # { id: 2, name: 'Frank' }
210
+ # ]
211
+ # ModelExample.create(array_of_attributes)
212
+ # ModelExample.all.count #=> 2
213
+ # ModelExample.destroy_all
214
+ # ModelExample.all.count #=> 0
215
+ #
216
+ # @return [void]
217
+ #
218
+ def delete_all
219
+ @object_array = []
220
+ indexes.values.each(&:remove_all)
221
+ nil
222
+ end
204
223
 
205
224
  # private
206
225
 
@@ -210,12 +229,13 @@ module ActiveModelPersistence
210
229
  #
211
230
  # @api private
212
231
  #
232
+ def object_array
233
+ @object_array ||= []
234
+ end
213
235
  end
214
236
 
215
237
  # rubocop:disable Metrics/BlockLength
216
238
  included do
217
- cattr_reader :object_array, instance_accessor: false, default: []
218
-
219
239
  # Returns true if this object hasn't been saved or destroyed yet
220
240
  #
221
241
  # @example
@@ -351,7 +371,7 @@ module ActiveModelPersistence
351
371
  def destroy
352
372
  if persisted?
353
373
  remove_from_indexes
354
- self.class.object_array.delete_if { |o| o.primary_key_value == primary_key_value }
374
+ self.class.object_array.delete_if { |o| o.primary_key == primary_key }
355
375
  end
356
376
  @new_record = false
357
377
  @destroyed = true
@@ -409,14 +429,13 @@ module ActiveModelPersistence
409
429
  # Creates a record with values matching those of the instance attributes
410
430
  # and returns its id.
411
431
  #
412
- # @return [Object] the primary_key_value of the created object
432
+ # @return [Object] the primary_key of the created object
413
433
  #
414
434
  # @api private
415
435
  #
416
436
  def _create
417
- return false unless primary_key_value?
418
-
419
- raise UniqueConstraintError if primary_key_index.include?(primary_key_value)
437
+ return false unless primary_key?
438
+ raise UniqueConstraintError if primary_key_index.include?(primary_key)
420
439
 
421
440
  self.class.object_array << self
422
441
 
@@ -424,7 +443,7 @@ module ActiveModelPersistence
424
443
 
425
444
  yield(self) if block_given?
426
445
 
427
- primary_key_value
446
+ primary_key
428
447
  end
429
448
 
430
449
  # Updates an object that is already in the object store
@@ -434,7 +453,7 @@ module ActiveModelPersistence
434
453
  # @api private
435
454
  #
436
455
  def _update
437
- raise RecordNotFound unless primary_key_index.include?(primary_key_value)
456
+ raise RecordNotFound unless primary_key_index.include?(primary_key)
438
457
 
439
458
  yield(self) if block_given?
440
459
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/core_ext/module'
4
-
5
3
  module ActiveModelPersistence
6
4
  # Exposes the `primary_key` accessor to read or write the primary key attribute value
7
5
  #
@@ -44,8 +42,7 @@ module ActiveModelPersistence
44
42
  # make these class methods on that class.
45
43
  #
46
44
  module ClassMethods
47
- # @!attribute [rw] primary_key
48
- # Identifies the attribute that the `primary_key_value` accessor maps to
45
+ # Identifies the attribute that the `primary_key` accessor maps to
49
46
  #
50
47
  # The primary key is 'id' by default.
51
48
  #
@@ -57,28 +54,33 @@ module ActiveModelPersistence
57
54
  # end
58
55
  # Employee.primary_key #=> :username
59
56
  #
60
- # @return [String] the attribute that the `primary_key` accessor is an alias for
57
+ # @return [Symbol] the attribute that the `primary_key` accessor is an alias for
61
58
  #
62
- # @api public
63
- end
59
+ def primary_key
60
+ @primary_key ||= 'id'
61
+ end
64
62
 
65
- included do
66
- # @!attribute [r] primary_key
67
- # Identifies the attribute that the `primary_key_value` accessor maps to
68
- #
69
- # The primary key is 'id' by default.
63
+ # Sets the attribute to use for the primary key
70
64
  #
71
65
  # @example
72
66
  # class Employee
73
67
  # include ActiveModelPersistence::PrimaryKey
74
68
  # attribute :username, :string
75
- # self.primary_key = :username
69
+ # primary_key = :username
76
70
  # end
77
- # Employee.primary_key #=> :username
71
+ # e = Employee.new(username: 'couballj')
72
+ # e.primary_key #=> 'couballj'
73
+ #
74
+ # @param attribute [Symbol] the attribute to use for the primary key
75
+ #
76
+ # @return [void]
78
77
  #
79
- # @return [String] the attribute that the `primary_key` accessor is an alias for
80
- cattr_accessor :primary_key, default: 'id', instance_writer: false
78
+ def primary_key=(attribute)
79
+ @primary_key = attribute.to_s
80
+ end
81
+ end
81
82
 
83
+ included do
82
84
  # Returns the primary key attribute's value
83
85
  #
84
86
  # @example
@@ -92,8 +94,8 @@ module ActiveModelPersistence
92
94
  #
93
95
  # @return [Object] the primary key attribute's value
94
96
  #
95
- def primary_key_value
96
- __send__(primary_key)
97
+ def primary_key
98
+ __send__(self.class.primary_key)
97
99
  end
98
100
 
99
101
  # Sets the primary key atribute's value
@@ -112,8 +114,8 @@ module ActiveModelPersistence
112
114
  #
113
115
  # @return [void]
114
116
  #
115
- def primary_key_value=(value)
116
- __send__("#{primary_key}=", value)
117
+ def primary_key=(value)
118
+ __send__("#{self.class.primary_key}=", value)
117
119
  end
118
120
 
119
121
  # Returns true if the primary key attribute's value is not null or empty
@@ -131,8 +133,8 @@ module ActiveModelPersistence
131
133
  #
132
134
  # @return [Boolean] true if the primary key attribute's value is not null or empty
133
135
  #
134
- def primary_key_value?
135
- primary_key_value.present?
136
+ def primary_key?
137
+ primary_key.present?
136
138
  end
137
139
  end
138
140
  end
@@ -47,7 +47,7 @@ module ActiveModelPersistence
47
47
  # @api private
48
48
  #
49
49
  def self.extended(base)
50
- base.index('primary_key', key_value_source: :primary_key_value, unique: true)
50
+ base.index('primary_key', key_value_source: :primary_key, unique: true)
51
51
  end
52
52
  end
53
53
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module ActiveModelPersistence
4
4
  # The version of the active_model_persistence gem
5
- VERSION = '0.4.0'
5
+ VERSION = '0.5.0'
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_model_persistence
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Couball