positioning 0.4.1 → 0.4.3

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: fdc57e74504d876181c7f4b4355f4a3b2831bb8da768164fa4ff6aaf00655164
4
- data.tar.gz: ed8daeb88c81490abfc233e9c853b19dd38da72e7ec5c05648cc4e221dbab62e
3
+ metadata.gz: c5d59cea57ca298c21e0628f0127b5a265dc10c511964ee9d8bd68509e05d1c5
4
+ data.tar.gz: 128d55b9f0f77920c288ca0986d4260fdaee20daf5fc5b780178d81f0c8fcccd
5
5
  SHA512:
6
- metadata.gz: 5ebe0ebd308d7937b6838d819e64bf8ce3728bf938c2c69b123c264cd351b8f6a20e66406abcda68c091ef4a6fdb270b638eccab0310eb1776ca8bd06ba7bded
7
- data.tar.gz: edcfe4c7f0ca38e6660f956910c6f7d6a70430ffe6949bb098c28ba37d95aaafc33cacdfd3e002a6384fb43c84e9c625b2cbf8498a541cc850bf9e9a9e85bf69
6
+ metadata.gz: 0d85df90cc7178941062d4e011e62ee857f0e24d08d36d676cbb64696b626da3b383edd66236d9dd5688e4cc0d87d3f96569495f5ae044ce0f8a6f461cad2c16
7
+ data.tar.gz: b8cada361907d53e53f0b9a93ba84d22a7dffc2a4be79914558638b4905e1305553c3c95f8055cc96931175e61208b4a928b3cc2702a7ab0ae54789fc6040db0
data/CHANGELOG.md CHANGED
@@ -1,10 +1,21 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.4.1] - 2024-10-12
3
+ ## [0.4.3] - 2024-11-18
4
+
5
+ - Add support for polymorphic `belongs_to` where we add both the `id` and the `type` to the scope.
6
+
7
+ ## [0.4.2] - 2024-11-08
8
+
9
+ NOTE: Versions 0.4.0 and 0.4.1 contain fatal flaws with the locking logic. Upgrade as soon as you can.
10
+
11
+ - Fix cases where locking wasn't executed where there were no associated scopes.
12
+ - Fix locking causing the in-memory record to be reloaded from the database. We only need the lock, not the reloaded record.
13
+
14
+ ## [0.4.1] - 2024-11-07
4
15
 
5
16
  - Fix locking where a `belongs_to` association is `optional: true`.
6
17
 
7
- ## [0.4.0] - 2024-10-12
18
+ ## [0.4.0] - 2024-11-07
8
19
 
9
20
  - BREAKING CHANGE: Advisory Lock has been removed. If you explicitly define `advisory_lock: false` in your `positioned` call, you'll need to remove this.
10
21
  - CAUTION: The Advisory Lock replacement is row locking. Where `belongs_to` associations exist, we lock the associated record(s), and that limits the locking scope down to the record's current scope, and potentially the scope it belonged to before a change in scope. If there are no `belongs_to` associations then the records that belong to the current (and potentially new) scope are locked, or all the records in the table are locked if there is no scope. Please report any deadlock issues.
data/Gemfile CHANGED
@@ -6,6 +6,8 @@ gemspec
6
6
  gem "rake", "~> 13.0"
7
7
 
8
8
  gem "minitest", "~> 5.0"
9
+ gem "minitest-hooks", "~> 1.5.1"
10
+ gem "mocha", "~> 2.1.0"
9
11
 
10
12
  gem "standard", "~> 1.3"
11
13
 
@@ -13,3 +15,17 @@ if ENV["RAILS_VERSION"]
13
15
  gem "activerecord", ENV["RAILS_VERSION"]
14
16
  gem "activesupport", ENV["RAILS_VERSION"]
15
17
  end
18
+
19
+ case ENV["DB"]
20
+ when "sqlite"
21
+ if ENV["RAILS_VERSION"] &&
22
+ Gem::Version.new(ENV["RAILS_VERSION"]) >= Gem::Version.new("7.2")
23
+ gem "sqlite3", "~> 2.2.0"
24
+ else
25
+ gem "sqlite3", "~> 1.7.2"
26
+ end
27
+ when "postgresql"
28
+ gem "pg", "~> 1.5.5"
29
+ else
30
+ gem "mysql2", "~> 0.5.6"
31
+ end
data/README.md CHANGED
@@ -32,6 +32,10 @@ You should also add an index to ensure that the `position` column value is uniqu
32
32
 
33
33
  The above assumes that your items are scoped to a parent table called `lists`.
34
34
 
35
+ If you have a polymorphic `belongs_to` then you'll want to add the type column to the index also:
36
+
37
+ `add_index :items, [:listable_id, :listable_type, :position], unique: true`
38
+
35
39
  The Positioning gem uses `0` and negative integers to rearrange the lists it manages so don't add database validations to restrict the usage of these. You are also restricted from using `0` and negative integers as position values. If you try, the position value will become `1`. If you try to set an explicit position value that is greater than the next available list position, it will be rounded down to that value.
36
40
 
37
41
  ### Declaring Positioning
@@ -40,10 +44,10 @@ To declare that your model should keep track of the position of its records you
40
44
 
41
45
  ```ruby
42
46
  # The scope is global (all records will belong to the same list) and the database column
43
- # is 'positioned'
47
+ # is 'position'
44
48
  positioned
45
49
 
46
- # The scope is on the belongs_to relationship 'list' and the database column is 'positioned'
50
+ # The scope is on the belongs_to relationship 'list' and the database column is 'position'
47
51
  # We check if the scope is a belongs_to relationship and use its declared foreign_key as
48
52
  # the scope value. In this case it would be 'list_id' since we haven't overridden the
49
53
  # default foreign key.
@@ -67,9 +71,9 @@ belongs_to :list
67
71
  belongs_to :category
68
72
  positioned on: [:list, :category, :enabled]
69
73
 
70
- # If you do not want to use Advisory Lock, you can disable it entirely by passing the 'advisory_lock' flag as false
71
- belongs_to :list
72
- positioned on: :list, advisory_lock: false
74
+ # If your belongs_to is polymorphic positioning will automatically add the type to the scope
75
+ belongs_to :listable, polymorphic: true
76
+ positioned on: :listable
73
77
  ```
74
78
 
75
79
  ### Initialising a List
@@ -192,17 +192,19 @@ module Positioning
192
192
  if scope_associations.present?
193
193
  scope_associations.each do |scope_association|
194
194
  if @positioned.persisted? && positioning_scope_changed?
195
- record_scope.first.send(scope_association)&.lock!
195
+ associated_record = record_scope.first.send(scope_association)
196
+ associated_record.class.base_class.lock.find(associated_record.id) if associated_record
196
197
  end
197
198
 
198
- @positioned.send(scope_association)&.lock!
199
+ associated_record = @positioned.send(scope_association)
200
+ associated_record.class.base_class.lock.find(associated_record.id) if associated_record
199
201
  end
200
202
  else
201
203
  if @positioned.persisted? && positioning_scope_changed?
202
- positioning_scope_was.lock!
204
+ positioning_scope_was.lock.all.load
203
205
  end
204
206
 
205
- positioning_scope.lock!
207
+ positioning_scope.lock.all.load
206
208
  end
207
209
  end
208
210
 
@@ -1,3 +1,3 @@
1
1
  module Positioning
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.3"
3
3
  end
data/lib/positioning.rb CHANGED
@@ -36,6 +36,7 @@ module Positioning
36
36
 
37
37
  if reflection&.belongs_to?
38
38
  positioning_columns[column][:scope_columns] << reflection.foreign_key
39
+ positioning_columns[column][:scope_columns] << reflection.foreign_type if reflection.polymorphic?
39
40
  positioning_columns[column][:scope_associations] << reflection.name
40
41
  else
41
42
  positioning_columns[column][:scope_columns] << scope_component
data/positioning.gemspec CHANGED
@@ -29,11 +29,6 @@ Gem::Specification.new do |spec|
29
29
  # Uncomment to register a new dependency of your gem
30
30
  spec.add_dependency "activesupport", ">= 6.1"
31
31
  spec.add_dependency "activerecord", ">= 6.1"
32
- spec.add_development_dependency "minitest-hooks", "~> 1.5.1"
33
- spec.add_development_dependency "mocha", "~> 2.1.0"
34
- spec.add_development_dependency "mysql2", "~> 0.5.6"
35
- spec.add_development_dependency "pg", "~> 1.5.5"
36
- spec.add_development_dependency "sqlite3", "~> 1.7.2"
37
32
 
38
33
  # For more information and examples about making a new gem, check out our
39
34
  # guide at: https://bundler.io/guides/creating_gem.html
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: positioning
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brendon Muir
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-06 00:00:00.000000000 Z
11
+ date: 2024-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,76 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '6.1'
41
- - !ruby/object:Gem::Dependency
42
- name: minitest-hooks
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 1.5.1
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 1.5.1
55
- - !ruby/object:Gem::Dependency
56
- name: mocha
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 2.1.0
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 2.1.0
69
- - !ruby/object:Gem::Dependency
70
- name: mysql2
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 0.5.6
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 0.5.6
83
- - !ruby/object:Gem::Dependency
84
- name: pg
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 1.5.5
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 1.5.5
97
- - !ruby/object:Gem::Dependency
98
- name: sqlite3
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: 1.7.2
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: 1.7.2
111
41
  description:
112
42
  email:
113
43
  - brendon@spike.net.nz