narabikae 0.2.1 → 0.3.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: 07a44a8622d1ba78a90fa807d5947713bb47fdff0cb644973d8a5657ce37d453
4
- data.tar.gz: 17dc1892a77e52ea46b6753cd621d5a0fb9f45ffd2c1ab0adbbac138063437ed
3
+ metadata.gz: 889a0fb05988806d1ff5ab57e02932cf4bf8a57ad788e3a4f094456e15e57902
4
+ data.tar.gz: 1dfb405bc128aacd6bae61b89e133af0aa40cf67b16638ba475bb1933584c855
5
5
  SHA512:
6
- metadata.gz: 3a459cabd5079dd5c308726e40ad42fdcbe082e6b266e94220d27cf336f3b62da6d5aba39df39c443079533509a31c20ff7b5ebffca2bfc25dece8e340f6ef7f
7
- data.tar.gz: 9875163ef2ef2ffb5f48ffde782883b215875c498ef214027be373a88ac6789f8f172db6480ac50eb4e44804da4b9cdc1bfacefcbadfef57d5f41c2b5c1558f5
6
+ metadata.gz: 0c2e99432062adc3745d8c6641d99bbd7a2b91a021103c552f3c4f9a7d6678370c344af81adf7d10a0ba3103730070bd8f7370fcb9c99a99dd06c8d01d89e882
7
+ data.tar.gz: 0aed46f7bf0ed8ae057324e17b99799d132e77244382ba0d945476221d3edb0d7c2f9444f2281b0d28a9e85e17fce9da1cb0eba13c27c613e4e4fe5da629bdaa
data/README.md CHANGED
@@ -69,6 +69,10 @@ class Task < ApplicationRecord
69
69
  # Used for validation of the internally generated order value.
70
70
  # This value should be equivalent to
71
71
  # the limit set in the DB column.
72
+ #
73
+ # default_position: optional
74
+ # Set where new/auto-set records are inserted.
75
+ # Accepts :first or :last (default).
72
76
  end
73
77
  ```
74
78
 
@@ -88,6 +92,16 @@ Task.order(:position).pluck(:name, :position)
88
92
  > [!NOTE]
89
93
  > The position is set using the before_create callback. Therefore, do not define validations such as presence on the attributes managed by this gem!
90
94
 
95
+ #### Default position
96
+
97
+ By default, new/auto-set records are inserted at the end of the list. To insert at the beginning instead:
98
+
99
+ ```rb
100
+ class Task < ApplicationRecord
101
+ narabikae :position, size: 200, default_position: :first
102
+ end
103
+ ```
104
+
91
105
  ## Usage Details
92
106
 
93
107
  ### Reorder
@@ -157,6 +171,45 @@ target.position
157
171
  # ex: target.move_to_position_between(tasks.first, nil)
158
172
  ```
159
173
 
174
+ ### Set without saving
175
+
176
+ If you want to set the new position value and save later (for example, in a form), use `set_<field>_after/before/between`. These methods only assign the new position value and do not persist the record.
177
+
178
+ ```ruby
179
+ target.set_position_after(tasks.last)
180
+ target.position
181
+ # => 'a3'
182
+ target.save
183
+ ```
184
+
185
+ You can also use setter-style aliases:
186
+
187
+ ```ruby
188
+ target.position_after = tasks.last
189
+ target.position_between = [tasks.first, tasks.last]
190
+ ```
191
+
192
+ #### Form-friendly setters
193
+
194
+ The setter aliases can be used directly in forms or `assign_attributes`. They accept a target record or a position key (string). For `*_between=`, you can pass an array or hash. Primary key inputs are not accepted; do your own lookup and pass the record or its position.
195
+
196
+ ```ruby
197
+ # position key input (e.g., from a hidden field)
198
+ task.assign_attributes(position_after: tasks.last.position)
199
+
200
+ # between using an array
201
+ task.position_between = [tasks.first, tasks.last]
202
+
203
+ # between using a hash (string or symbol keys)
204
+ task.position_between = { prev: tasks.first.position, next: tasks.last.position }
205
+ ```
206
+
207
+ If you need retries, use the method form and pass `challenge` there:
208
+
209
+ ```ruby
210
+ task.set_position_between(tasks.first, tasks.last, challenge: 15)
211
+ ```
212
+
160
213
  ### Scope
161
214
 
162
215
  You can use this when you want to manage independent positions within specific scopes, such as foreign keys.
@@ -170,7 +223,7 @@ end
170
223
  class Chapter < ApplicationRecord
171
224
  belongs_to :course
172
225
 
173
- narabikae :position, size: 100, scope: %i[course_id]
226
+ narabikae :position, size: 100, scope: :course_id
174
227
  end
175
228
 
176
229
  course = Course.create
@@ -216,6 +269,53 @@ ticket.move_to_position_between(t1, t2, challenge: 15)
216
269
 
217
270
  Feel free to message me on Github (kazu-2020)
218
271
 
272
+ ## Development
273
+
274
+ ### Supported versions (tested in CI)
275
+
276
+ - Ruby 3.1, 3.2, 3.3, 3.4, 4.0
277
+ - Rails 7.1, 7.2, 8.0, 8.1, and Rails main (via `railties` from `rails/rails`)
278
+
279
+ ### Test suite
280
+
281
+ Tests are Minitest-based and run against a dummy Rails app located at `test/dummy`.
282
+
283
+ Database targets:
284
+
285
+ - `TARGET_DB=mysql` (default)
286
+ - `TARGET_DB=postgres`
287
+ - `TARGET_DB=sqlite`
288
+
289
+ To spin up database services locally:
290
+
291
+ ```sh
292
+ docker compose up -d
293
+ ```
294
+
295
+ Run the full matrix locally (all databases):
296
+
297
+ ```sh
298
+ bundle exec rake test
299
+ ```
300
+
301
+ Run a single database:
302
+
303
+ ```sh
304
+ bundle exec rake test:postgres
305
+ ```
306
+
307
+ Run tests directly with Rails for a specific target:
308
+
309
+ ```sh
310
+ TARGET_DB=sqlite bin/rails test
311
+ ```
312
+
313
+ To test against a specific Rails version:
314
+
315
+ ```sh
316
+ BUNDLE_GEMFILE=gemfiles/rails_8_1.gemfile TARGET_DB=mysql bundle exec rake test
317
+ ```
318
+
219
319
  ## Contributing
220
320
 
221
321
  Please wait a moment... 🙏
@@ -11,36 +11,60 @@ module Narabikae
11
11
  # check valid key for fractional_indexer
12
12
  # when invalid key, raise FractionalIndexer::Error
13
13
  FractionalIndexer.generate_key(prev_key: record.send(option.field))
14
- option.scope.any? { |s| record.will_save_change_to_attribute?(s) } && !record.will_save_change_to_attribute?(option.field)
14
+ record.send(option.field).nil? ||
15
+ (option.scope.any? { |s| record.will_save_change_to_attribute?(s) } && !record.will_save_change_to_attribute?(option.field))
15
16
  rescue FractionalIndexer::Error
16
17
  true
17
18
  end
18
19
 
19
- def set_position
20
- record.send("#{option.field}=", position_generator.create_last_position)
20
+ def set_position(position = option.default_position)
21
+ new_position =
22
+ case position
23
+ when :first
24
+ position_generator.create_first_position
25
+ when :last
26
+ position_generator.create_last_position
27
+ end
28
+
29
+ record.send("#{option.field}=", new_position)
21
30
  end
22
31
 
23
- def move_to_after(target, **args)
32
+ def set_after(target, **args)
24
33
  new_position = position_generator.find_position_after(target, **args)
25
34
  return false if new_position.blank?
26
35
 
27
36
  record.send("#{option.field}=", new_position)
28
- record.save
29
37
  end
30
38
 
31
- def move_to_before(target, **args)
39
+ def set_before(target, **args)
32
40
  new_position = position_generator.find_position_before(target, **args)
33
41
  return false if new_position.blank?
34
42
 
35
43
  record.send("#{option.field}=", new_position)
36
- record.save
37
44
  end
38
45
 
39
- def move_to_between(prev_target, next_target, **args)
46
+ def set_between(prev_target, next_target, **args)
40
47
  new_position = position_generator.find_position_between(prev_target, next_target, **args)
41
48
  return false if new_position.blank?
42
49
 
43
50
  record.send("#{option.field}=", new_position)
51
+ end
52
+
53
+ def move_to_after(target, **args)
54
+ return false unless set_after(target, **args)
55
+
56
+ record.save
57
+ end
58
+
59
+ def move_to_before(target, **args)
60
+ return false unless set_before(target, **args)
61
+
62
+ record.save
63
+ end
64
+
65
+ def move_to_between(prev_target, next_target, **args)
66
+ return false unless set_between(prev_target, next_target, **args)
67
+
44
68
  record.save
45
69
  end
46
70
 
@@ -2,7 +2,7 @@ module Narabikae
2
2
  class Configuration
3
3
  # Sets the base value for FractionalIndexer configuration.
4
4
  #
5
- # @param int [Integer] The base value can be 10, 62, 94, with the default being 94.
5
+ # @param int [Integer] The base value can be 10, 62, 94, with the default being 62.
6
6
  # @return [void]
7
7
  def base=(int)
8
8
  FractionalIndexer.configure do |config|
@@ -1,16 +1,22 @@
1
1
  module Narabikae
2
2
  class Option
3
- attr_reader :field, :key_max_size, :scope
3
+ attr_reader :field, :key_max_size, :scope, :default_position
4
4
 
5
5
  # Initializes a new instance of the Option class.
6
6
  #
7
7
  # @param field [Symbol]
8
8
  # @param key_max_size [Integer] The maximum size of the key.
9
- # @param scope [Array<Symbol>] The scope of the option.
10
- def initialize(field:, key_max_size:, scope: [])
9
+ # @param scope [Symbol, Array<Symbol>] The scope of the option.
10
+ # @param default_position [Symbol] The default position when creating or auto setting.
11
+ def initialize(field:, key_max_size:, scope: [], default_position: :last)
11
12
  @field = field.to_sym
12
13
  @key_max_size = key_max_size.to_i
13
- @scope = scope.is_a?(Array) ? scope.map(&:to_sym) : []
14
+ @scope = Array.wrap(scope).map(&:to_sym)
15
+ @default_position = (default_position || :last).to_sym
16
+
17
+ unless %i[first last].include?(@default_position)
18
+ raise ArgumentError, "default_position must be :first or :last"
19
+ end
14
20
  end
15
21
  end
16
22
  end
@@ -16,23 +16,28 @@ module Narabikae
16
16
  FractionalIndexer.generate_key(prev_key: current_last_position)
17
17
  end
18
18
 
19
+ # Generates a new key for the first position
20
+ #
21
+ # @return [String] The newly generated key for the first position.
22
+ def create_first_position
23
+ FractionalIndexer.generate_key(next_key: current_first_position)
24
+ end
25
+
19
26
  # Finds the position after the specified target.
20
27
  # If generated key is invalid(ex: it already exists),
21
28
  # a new key is generated until the challenge count reaches the limit.
22
29
  # challenge count is 10 by default.
23
30
  #
24
- # @param target [#send(field)]
25
- # @param args [Hash] Additional arguments.
26
- # @option args [Integer] :challenge The number of times to attempt finding a valid position.
31
+ # @param target [ActiveRecord::Base, String]
32
+ # @param challenge [Integer] The number of times to attempt finding a valid position.
27
33
  # @return [String, nil] The generated key for the position after the target, or nil if no valid position is found.
28
- def find_position_after(target, **args)
29
- merged_args = { challenge: 10 }.merge(args)
34
+ def find_position_after(target, challenge: 10)
30
35
  # when target is nil, try to generate key from the last position
31
- target_key = target&.send(option.field) || current_last_position
36
+ target_key = extract_target_key(target) || current_last_position
32
37
  key = FractionalIndexer.generate_key(prev_key: target_key)
33
38
  return key if valid?(key)
34
39
 
35
- (merged_args[:challenge] || 0).times do |i|
40
+ (challenge || 0).times do |i|
36
41
  key = FractionalIndexer.generate_key(prev_key: target_key, next_key: key)
37
42
  key += random_fractional
38
43
  return key if valid?(key)
@@ -53,18 +58,16 @@ module Narabikae
53
58
  # position = Position.new
54
59
  # position.find_position_before(target, challenge: 5)
55
60
  #
56
- # @param target [#send(field)]
57
- # @param args [Hash] Additional arguments.
58
- # @option args [Integer] :challenge The number of times to attempt finding a valid position.
61
+ # @param target [ActiveRecord::Base, String]
62
+ # @param challenge [Integer] The number of times to attempt finding a valid position.
59
63
  # @return [String, nil] The generated key for the position before the target, or nil if no valid position is found.
60
- def find_position_before(target, **args)
61
- merged_args = { challenge: 10 }.merge(args)
64
+ def find_position_before(target, challenge: 10)
62
65
  # when target is nil, try to generate key from the first position
63
- target_key = target&.send(option.field) || current_first_position
66
+ target_key = extract_target_key(target) || current_first_position
64
67
  key = FractionalIndexer.generate_key(next_key: target_key)
65
68
  return key if valid?(key)
66
69
 
67
- (merged_args[:challenge] || 0).times do |i|
70
+ (challenge || 0).times do |i|
68
71
  key = FractionalIndexer.generate_key(prev_key: key, next_key: target_key)
69
72
  key += random_fractional
70
73
  return key if valid?(key)
@@ -77,25 +80,24 @@ module Narabikae
77
80
 
78
81
  # Finds the position between two targets.
79
82
  #
80
- # @param prev_target [#send(field)] The previous target.
81
- # @param next_target [#send(field)] The next target.
82
- # @param args [Hash] Additional arguments.
83
- # @option args [Integer] :challenge The number of times to attempt finding a valid position.
83
+ # @param prev_target [ActiveRecord::Base, String] The previous target.
84
+ # @param next_target [ActiveRecord::Base, String] The next target.
85
+ # @param challenge [Integer] The number of times to attempt finding a valid position.
84
86
  # @return [string, nil] The position between the two targets, or nil if no valid position is found.
85
- def find_position_between(prev_target, next_target, **args)
86
- return find_position_before(next_target, **args) if prev_target.blank?
87
- return find_position_after(prev_target, **args) if next_target.blank?
87
+ def find_position_between(prev_target, next_target, challenge: 10)
88
+ prev_key = extract_target_key(prev_target)
89
+ next_key = extract_target_key(next_target)
90
+ return find_position_before(next_target, challenge: challenge) if prev_key.blank?
91
+ return find_position_after(prev_target, challenge: challenge) if next_key.blank?
88
92
 
89
- merged_args = { challenge: 10 }.merge(args)
90
-
91
- prev_key, next_key = [ prev_target.send(option.field), next_target.send(option.field) ].minmax
93
+ prev_key, next_key = [ prev_key, next_key ].minmax
92
94
  key = FractionalIndexer.generate_key(
93
95
  prev_key: prev_key,
94
96
  next_key: next_key,
95
97
  )
96
98
  return key if valid?(key)
97
99
 
98
- (merged_args[:challenge] || 0).times do |i|
100
+ (challenge || 0).times do |i|
99
101
  key = FractionalIndexer.generate_key(prev_key: key, next_key: next_key)
100
102
  key += random_fractional
101
103
  return key if valid?(key)
@@ -123,7 +125,7 @@ module Narabikae
123
125
  end
124
126
 
125
127
  def model
126
- record.class.base_class
128
+ record.class.base_class.unscoped
127
129
  end
128
130
 
129
131
  # generate a random fractional part
@@ -148,5 +150,43 @@ module Narabikae
148
150
 
149
151
  capable?(key) && uniq?(key)
150
152
  end
153
+
154
+ def extract_target_key(target)
155
+ return if target.nil?
156
+ return target if target.is_a?(String)
157
+ unless target.is_a?(ActiveRecord::Base)
158
+ raise Narabikae::Error, "target must be an ActiveRecord object or position key string"
159
+ end
160
+
161
+ record_table = table_name_for_class(record)
162
+ target_table = table_name_for_class(target)
163
+ unless target_table && record_table && target_table == record_table
164
+ raise Narabikae::Error,
165
+ "target model mismatch: expected table #{record_table || 'unknown'}, got #{target_table || 'unknown'}"
166
+ end
167
+
168
+ mismatched_columns = mismatched_scope_columns(target)
169
+ if mismatched_columns.any?
170
+ raise Narabikae::Error, "target scope mismatch for columns: #{mismatched_columns.join(', ')}"
171
+ end
172
+ raise Narabikae::Error, "target missing #{option.field} field" unless target.respond_to?(option.field)
173
+
174
+ target.send(option.field)
175
+ end
176
+
177
+ def table_name_for_class(value)
178
+ klass = value.class
179
+ return unless klass.respond_to?(:table_name)
180
+
181
+ klass.table_name
182
+ end
183
+
184
+ def mismatched_scope_columns(target)
185
+ option.scope.select do |column|
186
+ !target.respond_to?(column) ||
187
+ !record.respond_to?(column) ||
188
+ target.public_send(column) != record.public_send(column)
189
+ end
190
+ end
151
191
  end
152
192
  end
@@ -1,3 +1,3 @@
1
1
  module Narabikae
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/narabikae.rb CHANGED
@@ -29,20 +29,50 @@ module Narabikae
29
29
  extend ActiveSupport::Concern
30
30
 
31
31
  class_methods do
32
- def narabikae(field = :position, size:, scope: [])
32
+ def narabikae(field = :position, size:, scope: [], default_position: :last)
33
33
  option = narabikae_option_store.register!(
34
34
  field.to_sym,
35
- Narabikae::Option.new(field: field, key_max_size: size, scope: scope)
35
+ Narabikae::Option.new(field: field, key_max_size: size, scope: scope, default_position: default_position)
36
36
  )
37
37
 
38
- before_create do
38
+ before_save -> {
39
39
  extension = Narabikae::ActiveRecordExtension.new(self, option)
40
- extension.set_position
40
+ extension.set_position(option.default_position) if extension.auto_set_position?
41
+ }
42
+
43
+ define_method :"set_#{field}_after" do |target = nil, **args|
44
+ extension = Narabikae::ActiveRecordExtension.new(self, option)
45
+ extension.set_after(target, **args)
46
+ end
47
+ alias_method :"#{field}_after=", :"set_#{field}_after"
48
+
49
+ define_method :"set_#{field}_before" do |target = nil, **args|
50
+ extension = Narabikae::ActiveRecordExtension.new(self, option)
51
+ extension.set_before(target, **args)
52
+ end
53
+ alias_method :"#{field}_before=", :"set_#{field}_before"
54
+
55
+ define_method :"set_#{field}_between" do |prev_target = nil, next_target = nil, **args|
56
+ extension = Narabikae::ActiveRecordExtension.new(self, option)
57
+ extension.set_between(prev_target, next_target, **args)
41
58
  end
59
+ define_method :"#{field}_between=" do |value|
60
+ prev_target = nil
61
+ next_target = nil
62
+
63
+ case value
64
+ when Array
65
+ prev_target, next_target = value
66
+ when Hash
67
+ payload = value.with_indifferent_access
68
+ prev_target = payload[:prev_target] || payload[:prev]
69
+ next_target = payload[:next_target] || payload[:next]
70
+ else
71
+ prev_target = value
72
+ end
42
73
 
43
- before_update do
44
74
  extension = Narabikae::ActiveRecordExtension.new(self, option)
45
- extension.set_position if extension.auto_set_position?
75
+ extension.set_between(prev_target, next_target)
46
76
  end
47
77
 
48
78
  define_method :"move_to_#{field}_after" do |target = nil, **args|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: narabikae
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - matazou
@@ -10,49 +10,49 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: fractional_indexer
13
+ name: activerecord
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 0.4.0
18
+ version: '7.1'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 0.4.0
25
+ version: '7.1'
26
26
  - !ruby/object:Gem::Dependency
27
- name: activerecord
27
+ name: railties
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: '6.1'
32
+ version: '7.1'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '6.1'
39
+ version: '7.1'
40
40
  - !ruby/object:Gem::Dependency
41
- name: activesupport
41
+ name: fractional_indexer
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: '6.1'
46
+ version: 0.4.0
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: '6.1'
53
+ version: 0.4.0
54
54
  - !ruby/object:Gem::Dependency
55
- name: rspec-rails
55
+ name: appraisal
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - ">="
@@ -66,47 +66,103 @@ dependencies:
66
66
  - !ruby/object:Gem::Version
67
67
  version: '0'
68
68
  - !ruby/object:Gem::Dependency
69
- name: rubocop-rails-omakase
69
+ name: debug
70
70
  requirement: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: 1.0.0
74
+ version: '1.9'
75
75
  type: :development
76
76
  prerelease: false
77
77
  version_requirements: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: 1.0.0
81
+ version: '1.9'
82
82
  - !ruby/object:Gem::Dependency
83
- name: rubocop-rspec
83
+ name: minitest
84
84
  requirement: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: 3.1.0
88
+ version: '5.0'
89
89
  type: :development
90
90
  prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: 3.1.0
95
+ version: '5.0'
96
96
  - !ruby/object:Gem::Dependency
97
- name: appraisal
97
+ name: mocha
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: mysql2
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ - !ruby/object:Gem::Dependency
125
+ name: pg
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ - !ruby/object:Gem::Dependency
139
+ name: sqlite3
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ type: :development
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ - !ruby/object:Gem::Dependency
153
+ name: rubocop-rails-omakase
98
154
  requirement: !ruby/object:Gem::Requirement
99
155
  requirements:
100
- - - '='
156
+ - - ">="
101
157
  - !ruby/object:Gem::Version
102
- version: 2.5.0
158
+ version: '0'
103
159
  type: :development
104
160
  prerelease: false
105
161
  version_requirements: !ruby/object:Gem::Requirement
106
162
  requirements:
107
- - - '='
163
+ - - ">="
108
164
  - !ruby/object:Gem::Version
109
- version: 2.5.0
165
+ version: '0'
110
166
  description: 'provides functionality similar to acts_as_list. However, by managing
111
167
  position using a fractional indexing system, it allows database record updates during
112
168
  reordering to be completed with only a single update (N = 1)!
@@ -122,7 +178,6 @@ files:
122
178
  - README.md
123
179
  - lib/narabikae.rb
124
180
  - lib/narabikae/active_record_extension.rb
125
- - lib/narabikae/active_record_handler.rb
126
181
  - lib/narabikae/configuration.rb
127
182
  - lib/narabikae/option.rb
128
183
  - lib/narabikae/option_store.rb
@@ -145,7 +200,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
145
200
  requirements:
146
201
  - - ">="
147
202
  - !ruby/object:Gem::Version
148
- version: '3.0'
203
+ version: '3.1'
149
204
  required_rubygems_version: !ruby/object:Gem::Requirement
150
205
  requirements:
151
206
  - - ">="
@@ -1,31 +0,0 @@
1
- module Narabikae
2
- class ActiveRecordHandler
3
- # Initializes a new instance of the ActiveRecordHandler class.
4
- #
5
- # @param record [Object] The ActiveRecord object.
6
- # @param column [Symbol] The column symbol.
7
- def initialize(record, column)
8
- @record = record
9
- @column = column
10
- end
11
-
12
- # Generates a new key for the last position
13
- #
14
- # @return [String] The newly generated key for the last position.
15
- def create_last_position
16
- FractionalIndexer.generate_key(prev_key: current_last_position)
17
- end
18
-
19
- private
20
-
21
- attr_reader :record, :column
22
-
23
- def current_last_position
24
- model.maximum(column)
25
- end
26
-
27
- def model
28
- record.class.base_class
29
- end
30
- end
31
- end