acts_as_list 1.0.1 → 1.0.4
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 +4 -4
- data/.travis.yml +30 -4
- data/Appraisals +12 -3
- data/CHANGELOG.md +24 -0
- data/Gemfile +2 -2
- data/README.md +2 -2
- data/acts_as_list.gemspec +0 -1
- data/gemfiles/rails_5_0.gemfile +1 -1
- data/gemfiles/rails_5_1.gemfile +2 -2
- data/gemfiles/rails_5_2.gemfile +2 -2
- data/gemfiles/rails_6_0.gemfile +1 -1
- data/gemfiles/rails_6_1.gemfile +31 -0
- data/lib/acts_as_list/active_record/acts/list.rb +1 -1
- data/lib/acts_as_list/active_record/acts/scope_method_definer.rb +8 -3
- data/lib/acts_as_list/version.rb +1 -1
- data/test/helper.rb +16 -0
- data/test/shared_list.rb +6 -0
- data/test/test_list.rb +19 -1
- data/test/test_scope_with_user_defined_foreign_key.rb +42 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a36b9ed8db57946d5ac96c829c68ce4f4107068628827840140e9dadb3c682fa
|
4
|
+
data.tar.gz: 60b6890922d26b913aed5a212eae7d228629c1ce3721dd0818ec2e5069697d25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bfced5d2dd4e50194eb8bdb92b244d40dd0a19df0ee663649510a965077a0d332715dc0100c1e9d006222e96e57745638c77812767b88ec7b9274dd350af4c1
|
7
|
+
data.tar.gz: 485f6be53763f1f112095075b1c69d6e620f89018c2e3435f3500decf986e110c832f78ce5db6462d6233d13816516a2c1d59df1e3c172455439a11704b1c8b5
|
data/.travis.yml
CHANGED
@@ -7,9 +7,11 @@ before_script:
|
|
7
7
|
- mysql -e 'create database acts_as_list;'
|
8
8
|
- psql -c 'create database acts_as_list;' -U postgres
|
9
9
|
rvm:
|
10
|
-
- 2.4
|
11
|
-
- 2.5
|
12
|
-
- 2.6
|
10
|
+
- 2.4
|
11
|
+
- 2.5
|
12
|
+
- 2.6
|
13
|
+
- 2.7
|
14
|
+
- 3.0
|
13
15
|
services:
|
14
16
|
- mysql
|
15
17
|
- postgresql
|
@@ -23,7 +25,31 @@ gemfile:
|
|
23
25
|
- gemfiles/rails_5_1.gemfile
|
24
26
|
- gemfiles/rails_5_2.gemfile
|
25
27
|
- gemfiles/rails_6_0.gemfile
|
28
|
+
- gemfiles/rails_6_1.gemfile
|
26
29
|
matrix:
|
27
30
|
exclude:
|
28
|
-
- rvm: 2.4
|
31
|
+
- rvm: 2.4
|
29
32
|
gemfile: gemfiles/rails_6_0.gemfile
|
33
|
+
- rvm: 2.4
|
34
|
+
gemfile: gemfiles/rails_6_1.gemfile
|
35
|
+
# Ruby 2.7 uses a `bigdecimal` version that doesn't support BigDecimal.new
|
36
|
+
# that Rails 4.2 uses. See also:
|
37
|
+
# https://github.com/ruby/bigdecimal#which-version-should-you-select
|
38
|
+
- rvm: 2.7
|
39
|
+
gemfile: gemfiles/rails_4_2.gemfile
|
40
|
+
# Ruby 2.7 warning `sqlite3-1.3.13/lib/sqlite3/statement.rb:108: warning: rb_tainted_str_new is deprecated`
|
41
|
+
# and job wil exceed the maximum log length
|
42
|
+
# see also: https://github.com/sparklemotion/sqlite3-ruby/issues/276
|
43
|
+
- rvm: 2.7
|
44
|
+
gemfile: gemfiles/rails_5_0.gemfile
|
45
|
+
env: DB=sqlite
|
46
|
+
# Rails <6 does not support Ruby 3, see:
|
47
|
+
# https://github.com/rails/rails/issues/40938#issuecomment-751898275
|
48
|
+
- rvm: 3.0
|
49
|
+
gemfile: gemfiles/rails_4_2.gemfile
|
50
|
+
- rvm: 3.0
|
51
|
+
gemfile: gemfiles/rails_5_0.gemfile
|
52
|
+
- rvm: 3.0
|
53
|
+
gemfile: gemfiles/rails_5_1.gemfile
|
54
|
+
- rvm: 3.0
|
55
|
+
gemfile: gemfiles/rails_5_2.gemfile
|
data/Appraisals
CHANGED
@@ -8,10 +8,18 @@ appraise "rails-4-2" do
|
|
8
8
|
group :test do
|
9
9
|
gem "test_after_commit", "~> 0.4.2"
|
10
10
|
end
|
11
|
+
group :sqlite do
|
12
|
+
gem "sqlite3", "~> 1.3.13"
|
13
|
+
end
|
14
|
+
|
11
15
|
gem "activerecord", "~> 4.2.0"
|
12
16
|
end
|
13
17
|
|
14
18
|
appraise "rails-5-0" do
|
19
|
+
group :sqlite do
|
20
|
+
gem "sqlite3", "~> 1.3.13"
|
21
|
+
end
|
22
|
+
|
15
23
|
gem "activerecord", "~> 5.0.0"
|
16
24
|
end
|
17
25
|
|
@@ -24,8 +32,9 @@ appraise "rails-5-2" do
|
|
24
32
|
end
|
25
33
|
|
26
34
|
appraise "rails-6-0" do
|
27
|
-
group :sqlite do
|
28
|
-
gem "sqlite3", "~> 1.4"
|
29
|
-
end
|
30
35
|
gem "activerecord", "~> 6.0.0"
|
31
36
|
end
|
37
|
+
|
38
|
+
appraise "rails-6-1" do
|
39
|
+
gem "activerecord", "6.1.0.rc1"
|
40
|
+
end
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## Unreleased
|
8
|
+
|
9
|
+
## v1.0.4 - 2021-04-20
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
- Add Tests ruby 2.7 and 3.0 [\#393](https://github.com/brendon/acts_as_list/pull/393) ([QWYNG])
|
13
|
+
|
14
|
+
## v1.0.3 - 2020-12-24
|
15
|
+
|
16
|
+
### Fixed
|
17
|
+
- Silence deprecation warnings in Rails 6 [\#384](https://github.com/brendon/acts_as_list/pull/384) ([h-lame])
|
18
|
+
- Add explicit requirement of ActiveSupport::Inflector [\#387](https://github.com/brendon/acts_as_list/pull/387) ([rdvdijk])
|
19
|
+
|
20
|
+
## v1.0.2 - 2020-09-14
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
- Get foreign key from reflections when possible [\#383](https://github.com/brendon/acts_as_list/pull/383) ([jefftsang])
|
24
|
+
|
25
|
+
### Removed
|
26
|
+
- gemspec: Drop defunct `rubyforge_project` directive [\#373](https://github.com/brendon/acts_as_list/pull/373) ([olleolleolle])
|
27
|
+
|
28
|
+
[olleolleolle]: https://github.com/olleolleolle
|
29
|
+
[jefftsang]: https://github.com/jefftsang
|
30
|
+
|
7
31
|
## v1.0.1 - 2020-02-27
|
8
32
|
|
9
33
|
### Fixed
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -108,7 +108,7 @@ end
|
|
108
108
|
When using PostgreSQL, it is also possible to leave this migration up to the database layer. Inside of the `change` block you could write:
|
109
109
|
|
110
110
|
```ruby
|
111
|
-
execute <<~SQL.
|
111
|
+
execute <<~SQL.squish
|
112
112
|
UPDATE todo_items
|
113
113
|
SET position = mapping.new_position
|
114
114
|
FROM (
|
@@ -282,7 +282,7 @@ All versions `0.1.5` onwards require Rails 3.0.x and higher.
|
|
282
282
|
|
283
283
|
We often hear complaints that `position` values are repeated, incorrect etc. For example, #254. To ensure data integrity, you should rely on your database. There are two things you can do:
|
284
284
|
|
285
|
-
1. Use constraints. If you model `Item` that `belongs_to` an `Order`, and it has a `position` column, then add a unique constraint on `items` with `[:order_id, :
|
285
|
+
1. Use constraints. If you model `Item` that `belongs_to` an `Order`, and it has a `position` column, then add a unique constraint on `items` with `[:order_id, :position]`. Think of it as a list invariant. What are the properties of your list that don't change no matter how many items you have in it? One such propery is that each item has a distinct position. Another _could be_ that position is always greater than 0. It is strongly recommended that you rely on your database to enforce these invariants or constraints. Here are the docs for [PostgreSQL](https://www.postgresql.org/docs/9.5/static/ddl-constraints.html) and [MySQL](https://dev.mysql.com/doc/refman/8.0/en/alter-table.html).
|
286
286
|
2. Use mutexes or row level locks. At its heart the duplicate problem is that of handling concurrency. Adding a contention resolution mechanism like locks will solve it to some extent. But it is not a solution or replacement for constraints. Locks are also prone to deadlocks.
|
287
287
|
|
288
288
|
As a library, `acts_as_list` may not always have all the context needed to apply these tools. They are much better suited at the application level.
|
data/acts_as_list.gemspec
CHANGED
@@ -13,7 +13,6 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.summary = "A gem adding sorting, reordering capabilities to an active_record model, allowing it to act as a list"
|
14
14
|
s.description = 'This "acts_as" extension provides the capabilities for sorting and reordering a number of objects in a list. The class that has this specified needs to have a "position" column defined as an integer on the mapped database table.'
|
15
15
|
s.license = "MIT"
|
16
|
-
s.rubyforge_project = "acts_as_list"
|
17
16
|
s.required_ruby_version = ">= 2.4.7"
|
18
17
|
|
19
18
|
if s.respond_to?(:metadata)
|
data/gemfiles/rails_5_0.gemfile
CHANGED
data/gemfiles/rails_5_1.gemfile
CHANGED
data/gemfiles/rails_5_2.gemfile
CHANGED
data/gemfiles/rails_6_0.gemfile
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "http://rubygems.org"
|
4
|
+
|
5
|
+
gem "rake"
|
6
|
+
gem "appraisal"
|
7
|
+
gem "activerecord", "6.1.0.rc1"
|
8
|
+
|
9
|
+
group :development do
|
10
|
+
gem "github_changelog_generator", "1.9.0"
|
11
|
+
end
|
12
|
+
|
13
|
+
group :test do
|
14
|
+
gem "minitest", "~> 5.0"
|
15
|
+
gem "timecop"
|
16
|
+
gem "mocha"
|
17
|
+
end
|
18
|
+
|
19
|
+
group :sqlite do
|
20
|
+
gem "sqlite3", "~> 1.4"
|
21
|
+
end
|
22
|
+
|
23
|
+
group :postgresql do
|
24
|
+
gem "pg", "~> 1.2.0"
|
25
|
+
end
|
26
|
+
|
27
|
+
group :mysql do
|
28
|
+
gem "mysql2", "~> 0.5.0"
|
29
|
+
end
|
30
|
+
|
31
|
+
gemspec path: "../"
|
@@ -226,7 +226,7 @@ module ActiveRecord
|
|
226
226
|
end
|
227
227
|
|
228
228
|
def acts_as_list_list
|
229
|
-
acts_as_list_class.unscope(:select, :where).where(scope_condition)
|
229
|
+
acts_as_list_class.default_scoped.unscope(:select, :where).where(scope_condition)
|
230
230
|
end
|
231
231
|
|
232
232
|
# Poorly named methods. They will insert the item at the desired position if the position
|
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require "active_support/inflector"
|
2
3
|
|
3
4
|
module ActiveRecord::Acts::List::ScopeMethodDefiner #:nodoc:
|
4
5
|
extend ActiveSupport::Inflector
|
5
6
|
|
6
7
|
def self.call(caller_class, scope)
|
7
|
-
scope = idify(scope) if scope.is_a?(Symbol)
|
8
|
+
scope = idify(caller_class, scope) if scope.is_a?(Symbol)
|
8
9
|
|
9
10
|
caller_class.class_eval do
|
10
11
|
define_method :scope_name do
|
@@ -64,9 +65,13 @@ module ActiveRecord::Acts::List::ScopeMethodDefiner #:nodoc:
|
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
67
|
-
def self.idify(name)
|
68
|
+
def self.idify(caller_class, name)
|
68
69
|
return name if name.to_s =~ /_id$/
|
69
70
|
|
70
|
-
|
71
|
+
if caller_class.reflections.key?(name.to_s)
|
72
|
+
caller_class.reflections[name.to_s].foreign_key.to_sym
|
73
|
+
else
|
74
|
+
foreign_key(name).to_sym
|
75
|
+
end
|
71
76
|
end
|
72
77
|
end
|
data/lib/acts_as_list/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -51,3 +51,19 @@ def assert_equal_or_nil(a, b)
|
|
51
51
|
assert_equal a, b
|
52
52
|
end
|
53
53
|
end
|
54
|
+
|
55
|
+
def assert_no_deprecation_warning_raised_by(failure_message = 'ActiveRecord deprecation warning raised when we didn\'t expect it', pass_message = 'No ActiveRecord deprecation raised')
|
56
|
+
original_behavior = ActiveSupport::Deprecation.behavior
|
57
|
+
ActiveSupport::Deprecation.behavior = :raise
|
58
|
+
begin
|
59
|
+
yield
|
60
|
+
rescue ActiveSupport::DeprecationException => e
|
61
|
+
flunk "#{failure_message}: #{e}"
|
62
|
+
rescue
|
63
|
+
raise
|
64
|
+
else
|
65
|
+
pass pass_message
|
66
|
+
end
|
67
|
+
ensure
|
68
|
+
ActiveSupport::Deprecation.behavior = original_behavior
|
69
|
+
end
|
data/test/shared_list.rb
CHANGED
@@ -314,5 +314,11 @@ module Shared
|
|
314
314
|
new.insert_at!(1)
|
315
315
|
end
|
316
316
|
end
|
317
|
+
|
318
|
+
def test_find_or_create_doesnt_raise_deprecation_warning
|
319
|
+
assert_no_deprecation_warning_raised_by('ActiveRecord deprecation warning raised when using `find_or_create_by` when we didn\'t expect it') do
|
320
|
+
ListMixin.where(parent_id: 5).find_or_create_by(pos: 5)
|
321
|
+
end
|
322
|
+
end
|
317
323
|
end
|
318
324
|
end
|
data/test/test_list.rb
CHANGED
@@ -11,7 +11,7 @@ def setup_db(position_options = {})
|
|
11
11
|
|
12
12
|
# AR caches columns options like defaults etc. Clear them!
|
13
13
|
ActiveRecord::Base.connection.create_table :mixins do |t|
|
14
|
-
t.column :pos, :integer, position_options unless position_options[:positive] && sqlite
|
14
|
+
t.column :pos, :integer, **position_options unless position_options[:positive] && sqlite
|
15
15
|
t.column :active, :boolean, default: true
|
16
16
|
t.column :parent_id, :integer
|
17
17
|
t.column :parent_type, :string
|
@@ -419,6 +419,12 @@ class DefaultScopedTest < ActsAsListTestCase
|
|
419
419
|
assert_equal_or_nil $default_position, new_noup.pos
|
420
420
|
end
|
421
421
|
|
422
|
+
def test_find_or_create_doesnt_raise_deprecation_warning
|
423
|
+
assert_no_deprecation_warning_raised_by('ActiveRecord deprecation warning raised when using `find_or_create_by` when we didn\'t expect it') do
|
424
|
+
DefaultScopedMixin.find_or_create_by(pos: 5)
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
422
428
|
def test_update_position
|
423
429
|
assert_equal [1, 2, 3, 4], DefaultScopedMixin.all.map(&:id)
|
424
430
|
DefaultScopedMixin.where(id: 2).first.set_list_position(4)
|
@@ -523,6 +529,12 @@ class DefaultScopedWhereTest < ActsAsListTestCase
|
|
523
529
|
assert_equal_or_nil $default_position, new_noup.pos
|
524
530
|
end
|
525
531
|
|
532
|
+
def test_find_or_create_doesnt_raise_deprecation_warning
|
533
|
+
assert_no_deprecation_warning_raised_by('ActiveRecord deprecation warning raised when using `find_or_create_by` when we didn\'t expect it') do
|
534
|
+
DefaultScopedWhereMixin.find_or_create_by(pos: 5)
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
526
538
|
def test_update_position
|
527
539
|
assert_equal [1, 2, 3, 4], DefaultScopedWhereMixin.for_active_false_tests.map(&:id)
|
528
540
|
DefaultScopedWhereMixin.for_active_false_tests.where(id: 2).first.set_list_position(4)
|
@@ -643,6 +655,12 @@ class MultipleListsTest < ActsAsListTestCase
|
|
643
655
|
assert_equal [1, 2, 3], ListMixin.where(:parent_id => 1).order('pos').map(&:pos)
|
644
656
|
assert_equal [1, 2, 3, 4, 5], ListMixin.where(:parent_id => 2).order('pos').map(&:pos)
|
645
657
|
end
|
658
|
+
|
659
|
+
def test_find_or_create_doesnt_raise_deprecation_warning
|
660
|
+
assert_no_deprecation_warning_raised_by('ActiveRecord deprecation warning raised when using `find_or_create_by` when we didn\'t expect it') do
|
661
|
+
ListMixin.where(:parent_id => 1).find_or_create_by(pos: 5)
|
662
|
+
end
|
663
|
+
end
|
646
664
|
end
|
647
665
|
|
648
666
|
class EnumArrayScopeListMixinTest < ActsAsListTestCase
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class Checklist < ActiveRecord::Base
|
4
|
+
has_many :checklist_items, foreign_key: 'list_id', inverse_of: :checklist
|
5
|
+
end
|
6
|
+
|
7
|
+
class ChecklistItem < ActiveRecord::Base
|
8
|
+
belongs_to :checklist, foreign_key: 'list_id', inverse_of: :checklist_items
|
9
|
+
acts_as_list scope: :checklist
|
10
|
+
end
|
11
|
+
|
12
|
+
class ScopeWithUserDefinedForeignKeyTest < Minitest::Test
|
13
|
+
def setup
|
14
|
+
ActiveRecord::Base.connection.create_table :checklists do |t|
|
15
|
+
end
|
16
|
+
|
17
|
+
ActiveRecord::Base.connection.create_table :checklist_items do |t|
|
18
|
+
t.column :list_id, :integer
|
19
|
+
t.column :position, :integer
|
20
|
+
end
|
21
|
+
|
22
|
+
ActiveRecord::Base.connection.schema_cache.clear!
|
23
|
+
[Checklist, ChecklistItem].each(&:reset_column_information)
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
teardown_db
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_scope_with_user_defined_foreign_key
|
33
|
+
checklist = Checklist.create
|
34
|
+
checklist_item_1 = checklist.checklist_items.create
|
35
|
+
checklist_item_2 = checklist.checklist_items.create
|
36
|
+
checklist_item_3 = checklist.checklist_items.create
|
37
|
+
|
38
|
+
assert_equal 1, checklist_item_1.position
|
39
|
+
assert_equal 2, checklist_item_2.position
|
40
|
+
assert_equal 3, checklist_item_3.position
|
41
|
+
end
|
42
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_list
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Swanand Pagnis
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-04-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -65,6 +65,7 @@ files:
|
|
65
65
|
- gemfiles/rails_5_1.gemfile
|
66
66
|
- gemfiles/rails_5_2.gemfile
|
67
67
|
- gemfiles/rails_6_0.gemfile
|
68
|
+
- gemfiles/rails_6_1.gemfile
|
68
69
|
- init.rb
|
69
70
|
- lib/acts_as_list.rb
|
70
71
|
- lib/acts_as_list/active_record/acts/active_record.rb
|
@@ -94,6 +95,7 @@ files:
|
|
94
95
|
- test/test_no_update_for_extra_classes.rb
|
95
96
|
- test/test_no_update_for_scope_destruction.rb
|
96
97
|
- test/test_no_update_for_subclasses.rb
|
98
|
+
- test/test_scope_with_user_defined_foreign_key.rb
|
97
99
|
homepage: http://github.com/brendon/acts_as_list
|
98
100
|
licenses:
|
99
101
|
- MIT
|
@@ -138,3 +140,4 @@ test_files:
|
|
138
140
|
- test/test_no_update_for_extra_classes.rb
|
139
141
|
- test/test_no_update_for_scope_destruction.rb
|
140
142
|
- test/test_no_update_for_subclasses.rb
|
143
|
+
- test/test_scope_with_user_defined_foreign_key.rb
|