active_model_persistence 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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