acts_as_list 0.7.4 → 0.7.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.travis.yml +15 -0
- data/Appraisals +13 -3
- data/CHANGELOG.md +77 -2
- data/Gemfile +2 -2
- data/README.md +2 -1
- data/gemfiles/rails_3_2.gemfile +2 -1
- data/gemfiles/rails_4_1.gemfile +2 -1
- data/gemfiles/rails_4_2.gemfile +2 -1
- data/gemfiles/rails_5_0.gemfile +24 -0
- data/lib/acts_as_list/active_record/acts/list.rb +94 -79
- data/lib/acts_as_list/version.rb +1 -1
- data/test/helper.rb +2 -2
- data/test/shared.rb +1 -0
- data/test/shared_list.rb +13 -1
- data/test/shared_no_addition.rb +11 -0
- data/test/shared_quoting.rb +21 -0
- data/test/test_joined_list.rb +64 -0
- data/test/test_list.rb +148 -3
- metadata +16 -11
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
OThlMWNiYjU3MGRmMGQzNjA5NzQ1MDk1MzdiYTg1MGFjODJlNDJmYQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d62dacdeb7972152a2ee04cee3cccb8ef26898d7
|
4
|
+
data.tar.gz: fe6b02bfa1c5ed33407d1852c7b988a1848c7cd4
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NmY4Y2FjY2U4YjczNjliZjFmYzYwYmMzYTNlNTA2MjU4NmVlODFmMzg1NGY0
|
11
|
-
OWNkN2Y4MGU2ZTM4YjM2YjY0MTZkNjcwMjk0NmQ1YzBkMmNjYjE=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
Mzg4NGQwNmY2NjdjN2MxZWIzYWE4MWNiOTlkMTc5NGM5NTRiMzRmY2MwNDVh
|
14
|
-
ODI2YTVhZmUwMzE1OTAwNzA1OWZjMjc3ZGNhZmI1Y2ZmNmU4NmYzNGQ3ZTc1
|
15
|
-
OGUyZDE0NjZkZTVjNmQxZTJhOWUyNjdhOWIwMjJiMTg2YzA2NWI=
|
6
|
+
metadata.gz: 6b376b14646463802f4aee7080663eefdb3d7b1a43088df7126f57c84ecfb0a8730470efe4b57758f2b2079d6bd52b19f2a80293b211095318425d5892194897
|
7
|
+
data.tar.gz: fa104b99749d08767074e96f5fea1e97590ee841673660c39d03bb3d2cd50a3d2db2de4d1d195d5503d1bfadec7cbe84e046714f0ab98d0d509bc4c4797949e2
|
data/.travis.yml
CHANGED
@@ -9,9 +9,24 @@ rvm:
|
|
9
9
|
- 1.9.3
|
10
10
|
- 2.0.0
|
11
11
|
- 2.1.0
|
12
|
+
- 2.2.2
|
12
13
|
- jruby-19mode
|
13
14
|
- rbx-2
|
14
15
|
gemfile:
|
15
16
|
- gemfiles/rails_3_2.gemfile
|
16
17
|
- gemfiles/rails_4_1.gemfile
|
17
18
|
- gemfiles/rails_4_2.gemfile
|
19
|
+
- gemfiles/rails_5_0.gemfile
|
20
|
+
matrix:
|
21
|
+
exclude:
|
22
|
+
- rvm: 1.9.3
|
23
|
+
gemfile: gemfiles/rails_5_0.gemfile
|
24
|
+
- rvm: 2.0.0
|
25
|
+
gemfile: gemfiles/rails_5_0.gemfile
|
26
|
+
- rvm: 2.1.0
|
27
|
+
gemfile: gemfiles/rails_5_0.gemfile
|
28
|
+
- rvm: jruby-19mode
|
29
|
+
gemfile: gemfiles/rails_5_0.gemfile
|
30
|
+
- rvm: rbx-2
|
31
|
+
gemfile: gemfiles/rails_5_0.gemfile
|
32
|
+
|
data/Appraisals
CHANGED
@@ -1,11 +1,21 @@
|
|
1
1
|
appraise "rails-3-2" do
|
2
|
-
gem "activerecord", "~> 3.2.
|
2
|
+
gem "activerecord", "~> 3.2.22.2"
|
3
|
+
group :test do
|
4
|
+
gem "after_commit_exception_notification"
|
5
|
+
end
|
3
6
|
end
|
4
7
|
|
5
8
|
appraise "rails-4-1" do
|
6
|
-
gem "activerecord", "~> 4.1.
|
9
|
+
gem "activerecord", "~> 4.1.16"
|
10
|
+
group :test do
|
11
|
+
gem "after_commit_exception_notification"
|
12
|
+
end
|
7
13
|
end
|
8
14
|
|
9
15
|
appraise "rails-4-2" do
|
10
|
-
gem "activerecord", "~> 4.2.
|
16
|
+
gem "activerecord", "~> 4.2.7"
|
17
|
+
end
|
18
|
+
|
19
|
+
appraise "rails-5-0" do
|
20
|
+
gem "activerecord", "~> 5.0.0"
|
11
21
|
end
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,82 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [v0.7.6](https://github.com/swanandp/acts_as_list/tree/v0.7.6) (2016-07-15)
|
4
|
+
[Full Changelog](https://github.com/swanandp/acts_as_list/compare/v0.7.5...v0.7.6)
|
5
|
+
|
6
|
+
**Closed issues:**
|
7
|
+
|
8
|
+
- add\_new\_at nil with scope causes NoMethodError [\#211](https://github.com/swanandp/acts_as_list/issues/211)
|
9
|
+
|
10
|
+
**Merged pull requests:**
|
11
|
+
|
12
|
+
- Add class method acts\_as\_list\_top as reader for configured top\_of\_list [\#213](https://github.com/swanandp/acts_as_list/pull/213) ([krzysiek1507](https://github.com/krzysiek1507))
|
13
|
+
- Bugfix/add new at nil on scope change [\#212](https://github.com/swanandp/acts_as_list/pull/212) ([greatghoul](https://github.com/greatghoul))
|
14
|
+
|
15
|
+
## [v0.7.5](https://github.com/swanandp/acts_as_list/tree/v0.7.5) (2016-06-30)
|
16
|
+
[Full Changelog](https://github.com/swanandp/acts_as_list/compare/v0.7.4...v0.7.5)
|
17
|
+
|
18
|
+
**Implemented enhancements:**
|
19
|
+
|
20
|
+
- Touch when reordering [\#173](https://github.com/swanandp/acts_as_list/pull/173) ([botandrose](https://github.com/botandrose))
|
21
|
+
|
22
|
+
**Closed issues:**
|
23
|
+
|
24
|
+
- Exception raised when calling destroy "NameError - instance variable @scope\_changed not defined:" [\#206](https://github.com/swanandp/acts_as_list/issues/206)
|
25
|
+
- Undefined instance variable @scope\_changed since 0.7.3 [\#199](https://github.com/swanandp/acts_as_list/issues/199)
|
26
|
+
- Reordering large lists is slow [\#198](https://github.com/swanandp/acts_as_list/issues/198)
|
27
|
+
- Reparenting child leaves gap in source list in rails 5 [\#194](https://github.com/swanandp/acts_as_list/issues/194)
|
28
|
+
- Support rails 5 ? [\#186](https://github.com/swanandp/acts_as_list/issues/186)
|
29
|
+
- I get a NoMethodError: undefined method `acts\_as\_list' when trying to include acts\_as\_list [\#176](https://github.com/swanandp/acts_as_list/issues/176)
|
30
|
+
- Phenomenon of mysterious value of the position is skipped by one [\#166](https://github.com/swanandp/acts_as_list/issues/166)
|
31
|
+
- Model.find being called twice with acts\_as\_list on destroy [\#161](https://github.com/swanandp/acts_as_list/issues/161)
|
32
|
+
- `scope\_changed?` problem with acts\_as\_paranoid [\#158](https://github.com/swanandp/acts_as_list/issues/158)
|
33
|
+
- Inconsistent behaviour between Symbol and Array scopes [\#155](https://github.com/swanandp/acts_as_list/issues/155)
|
34
|
+
- insert\_at doesn't seem to be working in ActiveRecord callback \(Rails 4.2\) [\#150](https://github.com/swanandp/acts_as_list/issues/150)
|
35
|
+
- Project Documentation link redirects to expired domain [\#149](https://github.com/swanandp/acts_as_list/issues/149)
|
36
|
+
- Problem when updating an position of array of AR objects. [\#137](https://github.com/swanandp/acts_as_list/issues/137)
|
37
|
+
- Unexpected behaviour when inserting consecutive items with default positions [\#124](https://github.com/swanandp/acts_as_list/issues/124)
|
38
|
+
- self.reload prone to error [\#122](https://github.com/swanandp/acts_as_list/issues/122)
|
39
|
+
- Rails 3.0.x in\_list causes the return of default\_scope [\#120](https://github.com/swanandp/acts_as_list/issues/120)
|
40
|
+
- Relationships with dependency:destroy cause ActiveRecord::RecordNotFound [\#118](https://github.com/swanandp/acts_as_list/issues/118)
|
41
|
+
- Using insert\_at with values with type String [\#117](https://github.com/swanandp/acts_as_list/issues/117)
|
42
|
+
- Batch setting of position [\#112](https://github.com/swanandp/acts_as_list/issues/112)
|
43
|
+
- position: 0 now makes model pushed to top? [\#110](https://github.com/swanandp/acts_as_list/issues/110)
|
44
|
+
- Create element in default position [\#103](https://github.com/swanandp/acts_as_list/issues/103)
|
45
|
+
- Enhancement: Expose scope object [\#97](https://github.com/swanandp/acts_as_list/issues/97)
|
46
|
+
- Shuffle list [\#96](https://github.com/swanandp/acts_as_list/issues/96)
|
47
|
+
- Creating an item with a nil scope should not add it to the list [\#92](https://github.com/swanandp/acts_as_list/issues/92)
|
48
|
+
- Performance Improvements [\#88](https://github.com/swanandp/acts_as_list/issues/88)
|
49
|
+
- has\_many :through or has\_many\_and\_belongs\_to\_many support [\#86](https://github.com/swanandp/acts_as_list/issues/86)
|
50
|
+
- ActiveRecord dependency causes rake assets:compile to fail without access to a database [\#84](https://github.com/swanandp/acts_as_list/issues/84)
|
51
|
+
- move\_higher/move\_lower vs move\_to\_top/move\_to\_bottom act differently when item is already at top or bottom [\#77](https://github.com/swanandp/acts_as_list/issues/77)
|
52
|
+
- Limiting the list size [\#61](https://github.com/swanandp/acts_as_list/issues/61)
|
53
|
+
- Adding multiple creates strange ordering [\#55](https://github.com/swanandp/acts_as_list/issues/55)
|
54
|
+
- Feature: sort [\#26](https://github.com/swanandp/acts_as_list/issues/26)
|
55
|
+
|
56
|
+
**Merged pull requests:**
|
57
|
+
|
58
|
+
- Removed duplicated assignment [\#207](https://github.com/swanandp/acts_as_list/pull/207) ([shunwen](https://github.com/shunwen))
|
59
|
+
- Quote all identifiers [\#205](https://github.com/swanandp/acts_as_list/pull/205) ([fabn](https://github.com/fabn))
|
60
|
+
- Start testing Rails 5 [\#203](https://github.com/swanandp/acts_as_list/pull/203) ([brendon](https://github.com/brendon))
|
61
|
+
- Lock! the record before destroying [\#201](https://github.com/swanandp/acts_as_list/pull/201) ([brendon](https://github.com/brendon))
|
62
|
+
- Fix ambiguous column error when joining some relations [\#180](https://github.com/swanandp/acts_as_list/pull/180) ([natw](https://github.com/natw))
|
63
|
+
|
64
|
+
## [v0.7.4](https://github.com/swanandp/acts_as_list/tree/v0.7.4) (2016-04-15)
|
65
|
+
[Full Changelog](https://github.com/swanandp/acts_as_list/compare/v0.7.3...v0.7.4)
|
66
|
+
|
67
|
+
**Closed issues:**
|
68
|
+
|
69
|
+
- Releasing a new gem version [\#196](https://github.com/swanandp/acts_as_list/issues/196)
|
70
|
+
|
71
|
+
**Merged pull requests:**
|
72
|
+
|
73
|
+
- Fix scope changed [\#200](https://github.com/swanandp/acts_as_list/pull/200) ([brendon](https://github.com/brendon))
|
74
|
+
|
3
75
|
## [v0.7.3](https://github.com/swanandp/acts_as_list/tree/v0.7.3) (2016-04-14)
|
4
|
-
[Full Changelog](https://github.com/swanandp/acts_as_list/compare/
|
76
|
+
[Full Changelog](https://github.com/swanandp/acts_as_list/compare/v0.7.2...v0.7.3)
|
77
|
+
|
78
|
+
## [v0.7.2](https://github.com/swanandp/acts_as_list/tree/v0.7.2) (2016-04-01)
|
79
|
+
[Full Changelog](https://github.com/swanandp/acts_as_list/compare/0.7.2...v0.7.2)
|
5
80
|
|
6
81
|
**Closed issues:**
|
7
82
|
|
@@ -238,4 +313,4 @@
|
|
238
313
|
|
239
314
|
|
240
315
|
|
241
|
-
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
316
|
+
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
data/Gemfile
CHANGED
@@ -9,12 +9,12 @@ platforms :rbx do
|
|
9
9
|
gem "rubysl-test-unit"
|
10
10
|
end
|
11
11
|
|
12
|
-
|
12
|
+
gem "rack", "~> 1", platforms: [:ruby_19, :ruby_20, :ruby_21, :jruby]
|
13
|
+
|
13
14
|
gemspec
|
14
15
|
|
15
16
|
gem "rake"
|
16
17
|
gem "appraisal"
|
17
|
-
# Used to automatically generate changelog file
|
18
18
|
gem "github_changelog_generator", "1.9.0"
|
19
19
|
|
20
20
|
group :test do
|
data/README.md
CHANGED
@@ -95,6 +95,8 @@ default: '1'. Use this option to define the top of the list. Use 0 to make the c
|
|
95
95
|
default: ':bottom'. Use this option to specify whether objects get added to the :top or :bottom of the list. `nil` will result in new items not being added to the list on create, i.e, position will be kept nil after create.
|
96
96
|
|
97
97
|
## Versions
|
98
|
+
As of version `0.7.5` Rails 5 is supported.
|
99
|
+
|
98
100
|
All versions `0.1.5` onwards require Rails 3.0.x and higher.
|
99
101
|
|
100
102
|
## Build Status
|
@@ -106,7 +108,6 @@ All versions `0.1.5` onwards require Rails 3.0.x and higher.
|
|
106
108
|
## Roadmap
|
107
109
|
|
108
110
|
1. Sort based feature
|
109
|
-
2. Rails 4 compatibility and bye bye Rails 2! Older versions would of course continue to work with Rails 2, but there won't be any support on those.
|
110
111
|
|
111
112
|
## Contributing to `acts_as_list`
|
112
113
|
|
data/gemfiles/rails_3_2.gemfile
CHANGED
@@ -4,10 +4,11 @@ source "http://rubygems.org"
|
|
4
4
|
|
5
5
|
gem "sqlite3", :platforms => [:ruby]
|
6
6
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby]
|
7
|
+
gem "rack", "~> 1", :platforms => [:ruby_19, :ruby_20, :ruby_21, :jruby]
|
7
8
|
gem "rake"
|
8
9
|
gem "appraisal"
|
9
10
|
gem "github_changelog_generator", "1.9.0"
|
10
|
-
gem "activerecord", "~> 3.2.
|
11
|
+
gem "activerecord", "~> 3.2.22.2"
|
11
12
|
|
12
13
|
group :test do
|
13
14
|
gem "minitest", "~> 5.0"
|
data/gemfiles/rails_4_1.gemfile
CHANGED
@@ -4,10 +4,11 @@ source "http://rubygems.org"
|
|
4
4
|
|
5
5
|
gem "sqlite3", :platforms => [:ruby]
|
6
6
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby]
|
7
|
+
gem "rack", "~> 1", :platforms => [:ruby_19, :ruby_20, :ruby_21, :jruby]
|
7
8
|
gem "rake"
|
8
9
|
gem "appraisal"
|
9
10
|
gem "github_changelog_generator", "1.9.0"
|
10
|
-
gem "activerecord", "~> 4.1.
|
11
|
+
gem "activerecord", "~> 4.1.16"
|
11
12
|
|
12
13
|
group :test do
|
13
14
|
gem "minitest", "~> 5.0"
|
data/gemfiles/rails_4_2.gemfile
CHANGED
@@ -4,10 +4,11 @@ source "http://rubygems.org"
|
|
4
4
|
|
5
5
|
gem "sqlite3", :platforms => [:ruby]
|
6
6
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby]
|
7
|
+
gem "rack", "~> 1", :platforms => [:ruby_19, :ruby_20, :ruby_21, :jruby]
|
7
8
|
gem "rake"
|
8
9
|
gem "appraisal"
|
9
10
|
gem "github_changelog_generator", "1.9.0"
|
10
|
-
gem "activerecord", "~> 4.2.
|
11
|
+
gem "activerecord", "~> 4.2.7"
|
11
12
|
|
12
13
|
group :test do
|
13
14
|
gem "minitest", "~> 5.0"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "http://rubygems.org"
|
4
|
+
|
5
|
+
gem "sqlite3", :platforms => [:ruby]
|
6
|
+
gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby]
|
7
|
+
gem "rack", "~> 1", :platforms => [:ruby_19, :ruby_20, :ruby_21, :jruby]
|
8
|
+
gem "rake"
|
9
|
+
gem "appraisal"
|
10
|
+
gem "github_changelog_generator", "1.9.0"
|
11
|
+
gem "activerecord", "~> 5.0.0"
|
12
|
+
|
13
|
+
group :test do
|
14
|
+
gem "minitest", "~> 5.0"
|
15
|
+
gem "test_after_commit", "~> 0.4.2"
|
16
|
+
end
|
17
|
+
|
18
|
+
platforms :rbx do
|
19
|
+
gem "rubysl", "~> 2.0"
|
20
|
+
gem "rubinius-developer_tools"
|
21
|
+
gem "rubysl-test-unit"
|
22
|
+
end
|
23
|
+
|
24
|
+
gemspec :path => "../"
|
@@ -74,8 +74,13 @@ module ActiveRecord
|
|
74
74
|
)
|
75
75
|
end
|
76
76
|
|
77
|
+
quoted_position_column = connection.quote_column_name(configuration[:column])
|
78
|
+
quoted_position_column_with_table_name = "#{quoted_table_name}.#{quoted_position_column}"
|
79
|
+
|
77
80
|
class_eval <<-EOV, __FILE__, __LINE__ + 1
|
78
|
-
|
81
|
+
def self.acts_as_list_top
|
82
|
+
#{configuration[:top_of_list]}.to_i
|
83
|
+
end
|
79
84
|
|
80
85
|
def acts_as_list_top
|
81
86
|
#{configuration[:top_of_list]}.to_i
|
@@ -111,23 +116,46 @@ module ActiveRecord
|
|
111
116
|
attr_accessible :#{configuration[:column]}
|
112
117
|
end
|
113
118
|
|
114
|
-
|
115
|
-
|
116
|
-
before_destroy :reload_position
|
117
|
-
after_destroy :decrement_positions_on_lower_items
|
118
|
-
|
119
|
-
before_update :check_scope
|
120
|
-
after_update :update_positions
|
119
|
+
scope :in_list, lambda { where(%q{#{quoted_position_column_with_table_name} IS NOT NULL}) }
|
121
120
|
|
122
|
-
|
121
|
+
def self.decrement_all
|
122
|
+
update_all_with_touch %q(#{quoted_position_column} = (#{quoted_position_column_with_table_name} - 1))
|
123
|
+
end
|
123
124
|
|
124
|
-
|
125
|
+
def self.increment_all
|
126
|
+
update_all_with_touch %q(#{quoted_position_column} = (#{quoted_position_column_with_table_name} + 1))
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.update_all_with_touch(updates)
|
130
|
+
record = new
|
131
|
+
attrs = record.send(:timestamp_attributes_for_update_in_model)
|
132
|
+
now = record.send(:current_time_from_proper_timezone)
|
133
|
+
|
134
|
+
query = attrs.map { |attr| %(\#{connection.quote_column_name(attr)} = :now) }
|
135
|
+
query.push updates
|
136
|
+
query = query.join(", ")
|
137
|
+
|
138
|
+
update_all([query, now: now])
|
139
|
+
end
|
125
140
|
EOV
|
126
141
|
|
142
|
+
attr_reader :position_changed
|
143
|
+
|
144
|
+
before_validation :check_top_position
|
145
|
+
|
146
|
+
before_destroy :lock!
|
147
|
+
after_destroy :decrement_positions_on_lower_items
|
148
|
+
|
149
|
+
before_update :check_scope
|
150
|
+
after_update :update_positions
|
151
|
+
|
152
|
+
after_commit :clear_scope_changed
|
153
|
+
|
127
154
|
if configuration[:add_new_at].present?
|
128
|
-
|
155
|
+
before_create "add_to_list_#{configuration[:add_new_at]}".to_sym
|
129
156
|
end
|
130
157
|
|
158
|
+
include ::ActiveRecord::Acts::List::InstanceMethods
|
131
159
|
end
|
132
160
|
end
|
133
161
|
|
@@ -232,10 +260,10 @@ module ActiveRecord
|
|
232
260
|
limit ||= acts_as_list_list.count
|
233
261
|
position_value = send(position_column)
|
234
262
|
acts_as_list_list.
|
235
|
-
where("#{
|
236
|
-
where("#{
|
263
|
+
where("#{quoted_position_column_with_table_name} < ?", position_value).
|
264
|
+
where("#{quoted_position_column_with_table_name} >= ?", position_value - limit).
|
237
265
|
limit(limit).
|
238
|
-
order("#{
|
266
|
+
order("#{quoted_position_column_with_table_name} ASC")
|
239
267
|
end
|
240
268
|
|
241
269
|
# Return the next lower item in the list.
|
@@ -250,10 +278,10 @@ module ActiveRecord
|
|
250
278
|
limit ||= acts_as_list_list.count
|
251
279
|
position_value = send(position_column)
|
252
280
|
acts_as_list_list.
|
253
|
-
where("#{
|
254
|
-
where("#{
|
281
|
+
where("#{quoted_position_column_with_table_name} > ?", position_value).
|
282
|
+
where("#{quoted_position_column_with_table_name} <= ?", position_value + limit).
|
255
283
|
limit(limit).
|
256
|
-
order("#{
|
284
|
+
order("#{quoted_position_column_with_table_name} ASC")
|
257
285
|
end
|
258
286
|
|
259
287
|
# Test if this record is in a list
|
@@ -298,7 +326,7 @@ module ActiveRecord
|
|
298
326
|
# A poorly named method. It will insert the item at the desired position if the position
|
299
327
|
# has been set manually using position=, not necessarily the bottom of the list
|
300
328
|
def add_to_list_bottom
|
301
|
-
if not_in_list? || internal_scope_changed? &&
|
329
|
+
if not_in_list? || internal_scope_changed? && !position_changed || default_position?
|
302
330
|
self[position_column] = bottom_position_in_list.to_i + 1
|
303
331
|
else
|
304
332
|
increment_positions_on_lower_items(self[position_column], id)
|
@@ -323,12 +351,11 @@ module ActiveRecord
|
|
323
351
|
|
324
352
|
# Returns the bottom item
|
325
353
|
def bottom_item(except = nil)
|
326
|
-
conditions =
|
327
|
-
conditions = except ? "#{self.class.primary_key} != #{self.class.connection.quote(except.id)}" : {}
|
354
|
+
conditions = except ? "#{quoted_table_name}.#{self.class.primary_key} != #{self.class.connection.quote(except.id)}" : {}
|
328
355
|
acts_as_list_list.in_list.where(
|
329
356
|
conditions
|
330
357
|
).order(
|
331
|
-
"#{
|
358
|
+
"#{quoted_position_column_with_table_name} DESC"
|
332
359
|
).first
|
333
360
|
end
|
334
361
|
|
@@ -344,56 +371,38 @@ module ActiveRecord
|
|
344
371
|
|
345
372
|
# This has the effect of moving all the higher items up one.
|
346
373
|
def decrement_positions_on_higher_items(position)
|
347
|
-
acts_as_list_list.where(
|
348
|
-
"#{position_column} <= #{position}"
|
349
|
-
).update_all(
|
350
|
-
"#{position_column} = (#{position_column} - 1)"
|
351
|
-
)
|
374
|
+
acts_as_list_list.where("#{quoted_position_column_with_table_name} <= ?", position).decrement_all
|
352
375
|
end
|
353
376
|
|
354
377
|
# This has the effect of moving all the lower items up one.
|
355
378
|
def decrement_positions_on_lower_items(position=nil)
|
356
379
|
return unless in_list?
|
357
380
|
position ||= send(position_column).to_i
|
358
|
-
acts_as_list_list.where(
|
359
|
-
"#{position_column} > #{position}"
|
360
|
-
).update_all(
|
361
|
-
"#{position_column} = (#{position_column} - 1)"
|
362
|
-
)
|
381
|
+
acts_as_list_list.where("#{quoted_position_column_with_table_name} > ?", position).decrement_all
|
363
382
|
end
|
364
383
|
|
365
384
|
# This has the effect of moving all the higher items down one.
|
366
385
|
def increment_positions_on_higher_items
|
367
386
|
return unless in_list?
|
368
|
-
acts_as_list_list.where(
|
369
|
-
"#{position_column} < #{send(position_column).to_i}"
|
370
|
-
).update_all(
|
371
|
-
"#{position_column} = (#{position_column} + 1)"
|
372
|
-
)
|
387
|
+
acts_as_list_list.where("#{quoted_position_column_with_table_name} < #{send(position_column).to_i}").increment_all
|
373
388
|
end
|
374
389
|
|
375
390
|
# This has the effect of moving all the lower items down one.
|
376
391
|
def increment_positions_on_lower_items(position, avoid_id = nil)
|
377
|
-
avoid_id_condition = avoid_id ? " AND #{self.class.primary_key} != #{self.class.connection.quote(avoid_id)}" : ''
|
392
|
+
avoid_id_condition = avoid_id ? " AND #{quoted_table_name}.#{self.class.primary_key} != #{self.class.connection.quote(avoid_id)}" : ''
|
378
393
|
|
379
|
-
acts_as_list_list.where(
|
380
|
-
"#{position_column} >= #{position}#{avoid_id_condition}"
|
381
|
-
).update_all(
|
382
|
-
"#{position_column} = (#{position_column} + 1)"
|
383
|
-
)
|
394
|
+
acts_as_list_list.where("#{quoted_position_column_with_table_name} >= #{position}#{avoid_id_condition}").increment_all
|
384
395
|
end
|
385
396
|
|
386
397
|
# Increments position (<tt>position_column</tt>) of all items in the list.
|
387
398
|
def increment_positions_on_all_items
|
388
|
-
acts_as_list_list.
|
389
|
-
"#{position_column} = (#{position_column} + 1)"
|
390
|
-
)
|
399
|
+
acts_as_list_list.increment_all
|
391
400
|
end
|
392
401
|
|
393
402
|
# Reorders intermediate items to support moving an item from old_position to new_position.
|
394
403
|
def shuffle_positions_on_intermediate_items(old_position, new_position, avoid_id = nil)
|
395
404
|
return if old_position == new_position
|
396
|
-
avoid_id_condition = avoid_id ? " AND #{self.class.primary_key} != #{self.class.connection.quote(avoid_id)}" : ''
|
405
|
+
avoid_id_condition = avoid_id ? " AND #{quoted_table_name}.#{self.class.primary_key} != #{self.class.connection.quote(avoid_id)}" : ''
|
397
406
|
|
398
407
|
if old_position < new_position
|
399
408
|
# Decrement position of intermediate items
|
@@ -401,37 +410,35 @@ module ActiveRecord
|
|
401
410
|
# e.g., if moving an item from 2 to 5,
|
402
411
|
# move [3, 4, 5] to [2, 3, 4]
|
403
412
|
acts_as_list_list.where(
|
404
|
-
"#{
|
413
|
+
"#{quoted_position_column_with_table_name} > ?", old_position
|
405
414
|
).where(
|
406
|
-
"#{
|
407
|
-
).
|
408
|
-
"#{position_column} = (#{position_column} - 1)"
|
409
|
-
)
|
415
|
+
"#{quoted_position_column_with_table_name} <= #{new_position}#{avoid_id_condition}"
|
416
|
+
).decrement_all
|
410
417
|
else
|
411
418
|
# Increment position of intermediate items
|
412
419
|
#
|
413
420
|
# e.g., if moving an item from 5 to 2,
|
414
421
|
# move [2, 3, 4] to [3, 4, 5]
|
415
422
|
acts_as_list_list.where(
|
416
|
-
"#{
|
423
|
+
"#{quoted_position_column_with_table_name} >= ?", new_position
|
417
424
|
).where(
|
418
|
-
"#{
|
419
|
-
).
|
420
|
-
"#{position_column} = (#{position_column} + 1)"
|
421
|
-
)
|
425
|
+
"#{quoted_position_column_with_table_name} < #{old_position}#{avoid_id_condition}"
|
426
|
+
).increment_all
|
422
427
|
end
|
423
428
|
end
|
424
429
|
|
425
430
|
def insert_at_position(position)
|
426
431
|
return set_list_position(position) if new_record?
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
432
|
+
with_lock do
|
433
|
+
if in_list?
|
434
|
+
old_position = send(position_column).to_i
|
435
|
+
return if position == old_position
|
436
|
+
shuffle_positions_on_intermediate_items(old_position, position)
|
437
|
+
else
|
438
|
+
increment_positions_on_lower_items(position)
|
439
|
+
end
|
440
|
+
set_list_position(position)
|
433
441
|
end
|
434
|
-
set_list_position(position)
|
435
442
|
end
|
436
443
|
|
437
444
|
# used by insert_at_position instead of remove_from_list, as postgresql raises error if position_column has non-null constraint
|
@@ -448,37 +455,31 @@ module ActiveRecord
|
|
448
455
|
new_position = send(position_column).to_i
|
449
456
|
|
450
457
|
return unless acts_as_list_list.where(
|
451
|
-
"#{
|
458
|
+
"#{quoted_position_column_with_table_name} = #{new_position}"
|
452
459
|
).count > 1
|
453
460
|
shuffle_positions_on_intermediate_items old_position, new_position, id
|
454
461
|
end
|
455
462
|
|
456
463
|
def internal_scope_changed?
|
457
464
|
return @scope_changed if defined?(@scope_changed)
|
458
|
-
|
465
|
+
|
459
466
|
@scope_changed = scope_changed?
|
460
467
|
end
|
461
468
|
|
462
|
-
|
463
|
-
|
464
|
-
@changed_attributes.each do |k, _|
|
465
|
-
if self.class.column_names.include? k
|
466
|
-
@changed_attributes[k], self[k] = self[k], @changed_attributes[k]
|
467
|
-
end
|
468
|
-
end
|
469
|
+
def clear_scope_changed
|
470
|
+
remove_instance_variable(:@scope_changed) if defined?(@scope_changed)
|
469
471
|
end
|
470
472
|
|
471
473
|
def check_scope
|
472
474
|
if internal_scope_changed?
|
473
|
-
|
475
|
+
cached_changes = changes
|
476
|
+
|
477
|
+
cached_changes.each { |attribute, values| self[attribute] = values[0] }
|
474
478
|
send('decrement_positions_on_lower_items') if lower_item
|
475
|
-
|
476
|
-
send("add_to_list_#{add_new_at}")
|
477
|
-
end
|
478
|
-
end
|
479
|
+
cached_changes.each { |attribute, values| self[attribute] = values[1] }
|
479
480
|
|
480
|
-
|
481
|
-
|
481
|
+
send("add_to_list_#{add_new_at}") if add_new_at.present?
|
482
|
+
end
|
482
483
|
end
|
483
484
|
|
484
485
|
# This check is skipped if the position is currently the default position from the table
|
@@ -488,6 +489,20 @@ module ActiveRecord
|
|
488
489
|
self[position_column] = acts_as_list_top
|
489
490
|
end
|
490
491
|
end
|
492
|
+
|
493
|
+
# When using raw column name it must be quoted otherwise it can raise syntax errors with SQL keywords (e.g. order)
|
494
|
+
def quoted_position_column
|
495
|
+
@_quoted_position_column ||= self.class.connection.quote_column_name(position_column)
|
496
|
+
end
|
497
|
+
|
498
|
+
# Used in order clauses
|
499
|
+
def quoted_table_name
|
500
|
+
@_quoted_table_name ||= acts_as_list_class.quoted_table_name
|
501
|
+
end
|
502
|
+
|
503
|
+
def quoted_position_column_with_table_name
|
504
|
+
@_quoted_position_column_with_table_name ||= "#{quoted_table_name}.#{quoted_position_column}"
|
505
|
+
end
|
491
506
|
end
|
492
507
|
end
|
493
508
|
end
|
data/lib/acts_as_list/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -12,9 +12,9 @@ require "minitest/autorun"
|
|
12
12
|
require "#{File.dirname(__FILE__)}/../init"
|
13
13
|
|
14
14
|
if defined?(ActiveRecord::VERSION) &&
|
15
|
-
ActiveRecord::VERSION::MAJOR
|
16
|
-
(ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2)
|
15
|
+
ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2
|
17
16
|
|
17
|
+
# Was removed in Rails 5 and is effectively true.
|
18
18
|
ActiveRecord::Base.raise_in_transactional_callbacks = true
|
19
19
|
end
|
20
20
|
|
data/test/shared.rb
CHANGED
data/test/shared_list.rb
CHANGED
@@ -104,6 +104,12 @@ module Shared
|
|
104
104
|
|
105
105
|
new4.reload
|
106
106
|
assert_equal 5, new4.pos
|
107
|
+
|
108
|
+
last1 = ListMixin.order('pos').last
|
109
|
+
last2 = ListMixin.order('pos').last
|
110
|
+
last1.insert_at(1)
|
111
|
+
last2.insert_at(1)
|
112
|
+
assert_equal [1, 2, 3, 4, 5], ListMixin.where(parent_id: 20).order('pos').map(&:pos)
|
107
113
|
end
|
108
114
|
|
109
115
|
def test_delete_middle
|
@@ -142,7 +148,7 @@ module Shared
|
|
142
148
|
|
143
149
|
def test_update_position_when_scope_changes
|
144
150
|
assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
|
145
|
-
|
151
|
+
ListMixin.create(parent_id: 6)
|
146
152
|
|
147
153
|
ListMixin.where(id: 2).first.move_within_scope(6)
|
148
154
|
|
@@ -246,5 +252,11 @@ module Shared
|
|
246
252
|
|
247
253
|
assert_equal [5, 1, 6, 2, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
|
248
254
|
end
|
255
|
+
|
256
|
+
def test_non_persisted_records_dont_get_lock_called
|
257
|
+
new = ListMixin.new(parent_id: 5)
|
258
|
+
|
259
|
+
new.destroy
|
260
|
+
end
|
249
261
|
end
|
250
262
|
end
|
data/test/shared_no_addition.rb
CHANGED
@@ -21,5 +21,16 @@ module Shared
|
|
21
21
|
assert !new.in_list?
|
22
22
|
end
|
23
23
|
|
24
|
+
def test_update_scope_does_not_add_to_list
|
25
|
+
new = NoAdditionMixin.create
|
26
|
+
|
27
|
+
new.update_attribute(:parent_id, 20)
|
28
|
+
new.reload
|
29
|
+
assert !new.in_list?
|
30
|
+
|
31
|
+
new.update_attribute(:parent_id, 5)
|
32
|
+
new.reload
|
33
|
+
assert !new.in_list?
|
34
|
+
end
|
24
35
|
end
|
25
36
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Shared
|
2
|
+
module Quoting
|
3
|
+
|
4
|
+
def setup
|
5
|
+
3.times { |counter| QuotedList.create! order: counter }
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_create
|
9
|
+
assert_equal QuotedList.in_list.size, 3
|
10
|
+
end
|
11
|
+
|
12
|
+
# This test execute raw queries involving table name
|
13
|
+
def test_moving
|
14
|
+
item = QuotedList.first
|
15
|
+
item.higher_items
|
16
|
+
item.lower_items
|
17
|
+
item.send :bottom_item # Part of private api
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
4
|
+
ActiveRecord::Schema.verbose = false
|
5
|
+
|
6
|
+
class Section < ActiveRecord::Base
|
7
|
+
has_many :items
|
8
|
+
acts_as_list
|
9
|
+
|
10
|
+
scope :visible, -> { where(visible: true) }
|
11
|
+
end
|
12
|
+
|
13
|
+
class Item < ActiveRecord::Base
|
14
|
+
belongs_to :section
|
15
|
+
acts_as_list scope: :section
|
16
|
+
|
17
|
+
scope :visible, -> { where(visible: true).joins(:section).merge(Section.visible) }
|
18
|
+
end
|
19
|
+
|
20
|
+
class JoinedTestCase < Minitest::Test
|
21
|
+
def setup
|
22
|
+
ActiveRecord::Base.connection.create_table :sections do |t|
|
23
|
+
t.column :position, :integer
|
24
|
+
t.column :visible, :boolean, default: true
|
25
|
+
end
|
26
|
+
|
27
|
+
ActiveRecord::Base.connection.create_table :items do |t|
|
28
|
+
t.column :position, :integer
|
29
|
+
t.column :section_id, :integer
|
30
|
+
t.column :visible, :boolean, default: true
|
31
|
+
end
|
32
|
+
|
33
|
+
ActiveRecord::Base.connection.schema_cache.clear!
|
34
|
+
[Section, Item].each(&:reset_column_information)
|
35
|
+
super
|
36
|
+
end
|
37
|
+
|
38
|
+
def teardown
|
39
|
+
ActiveRecord::Base.connection.tables.each do |table|
|
40
|
+
ActiveRecord::Base.connection.drop_table(table)
|
41
|
+
end
|
42
|
+
super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# joining the relation returned by `#higher_items` or `#lower_items` to another table
|
47
|
+
# previously could result in ambiguous column names in the query
|
48
|
+
class TestHigherLowerItems < JoinedTestCase
|
49
|
+
def test_higher_items
|
50
|
+
section = Section.create
|
51
|
+
item1 = Item.create section: section
|
52
|
+
item2 = Item.create section: section
|
53
|
+
item3 = Item.create section: section
|
54
|
+
assert_equal item3.higher_items.visible, [item1, item2]
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_lower_items
|
58
|
+
section = Section.create
|
59
|
+
item1 = Item.create section: section
|
60
|
+
item2 = Item.create section: section
|
61
|
+
item3 = Item.create section: section
|
62
|
+
assert_equal item1.lower_items.visible, [item2, item3]
|
63
|
+
end
|
64
|
+
end
|
data/test/test_list.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# NOTE: following now done in helper.rb (better Readability)
|
2
2
|
require 'helper'
|
3
3
|
|
4
|
-
ActiveRecord::Base.establish_connection(
|
4
|
+
ActiveRecord::Base.establish_connection(
|
5
|
+
adapter: "sqlite3",
|
6
|
+
database: 'file:memdb1?mode=memory&cache=shared'
|
7
|
+
)
|
5
8
|
ActiveRecord::Schema.verbose = false
|
6
9
|
|
7
10
|
def setup_db(position_options = {})
|
@@ -16,9 +19,14 @@ def setup_db(position_options = {})
|
|
16
19
|
t.column :state, :integer
|
17
20
|
end
|
18
21
|
|
22
|
+
# This table is used to test table names and column names quoting
|
23
|
+
ActiveRecord::Base.connection.create_table 'table-name' do |t|
|
24
|
+
t.column :order, :integer
|
25
|
+
end
|
26
|
+
|
19
27
|
mixins = [ Mixin, ListMixin, ListMixinSub1, ListMixinSub2, ListWithStringScopeMixin,
|
20
28
|
ArrayScopeListMixin, ZeroBasedMixin, DefaultScopedMixin,
|
21
|
-
DefaultScopedWhereMixin, TopAdditionMixin, NoAdditionMixin ]
|
29
|
+
DefaultScopedWhereMixin, TopAdditionMixin, NoAdditionMixin, QuotedList ]
|
22
30
|
|
23
31
|
mixins << EnumArrayScopeListMixin if rails_4
|
24
32
|
|
@@ -42,7 +50,13 @@ def rails_4
|
|
42
50
|
end
|
43
51
|
|
44
52
|
def teardown_db
|
45
|
-
ActiveRecord::
|
53
|
+
if ActiveRecord::VERSION::MAJOR >= 5
|
54
|
+
tables = ActiveRecord::Base.connection.data_sources
|
55
|
+
else
|
56
|
+
tables = ActiveRecord::Base.connection.tables
|
57
|
+
end
|
58
|
+
|
59
|
+
tables.each do |table|
|
46
60
|
ActiveRecord::Base.connection.drop_table(table)
|
47
61
|
end
|
48
62
|
end
|
@@ -149,6 +163,18 @@ end
|
|
149
163
|
class TheBaseSubclass < TheBaseClass
|
150
164
|
end
|
151
165
|
|
166
|
+
class DBConfigTest < Minitest::Test
|
167
|
+
def test_db_config
|
168
|
+
# make sure sqlite3 accepts multi threaded access
|
169
|
+
assert_equal "file:memdb1?mode=memory&cache=shared", ActiveRecord::Base.connection.pool.spec.config[:database]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
class QuotedList < ActiveRecord::Base
|
174
|
+
self.table_name = 'table-name'
|
175
|
+
acts_as_list column: :order
|
176
|
+
end
|
177
|
+
|
152
178
|
class ActsAsListTestCase < Minitest::Test
|
153
179
|
# No default test required as this class is abstract.
|
154
180
|
# Need for test/unit.
|
@@ -184,6 +210,37 @@ class ListTest < ActsAsListTestCase
|
|
184
210
|
setup_db
|
185
211
|
super
|
186
212
|
end
|
213
|
+
|
214
|
+
def test_insert_race_condition
|
215
|
+
# the bigger n is the more likely we will have a race condition
|
216
|
+
n = 1000
|
217
|
+
(1..n).each do |counter|
|
218
|
+
node = ListMixin.new parent_id: 1
|
219
|
+
node.pos = counter
|
220
|
+
node.save!
|
221
|
+
end
|
222
|
+
|
223
|
+
wait_for_it = true
|
224
|
+
threads = []
|
225
|
+
4.times do |i|
|
226
|
+
threads << Thread.new do
|
227
|
+
true while wait_for_it
|
228
|
+
ActiveRecord::Base.connection_pool.with_connection do |c|
|
229
|
+
n.times do
|
230
|
+
begin
|
231
|
+
ListMixin.where(parent_id: 1).order(:pos).last.insert_at(1)
|
232
|
+
rescue Exception
|
233
|
+
# ignore SQLite3::SQLException due to table locking
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
wait_for_it = false
|
240
|
+
threads.each(&:join)
|
241
|
+
|
242
|
+
assert_equal (1..n).to_a, ListMixin.where(parent_id: 1).order('pos').map(&:pos)
|
243
|
+
end
|
187
244
|
end
|
188
245
|
|
189
246
|
class ListWithCallbackTest < ActsAsListTestCase
|
@@ -243,6 +300,15 @@ class ArrayScopeListTestWithDefault < ActsAsListTestCase
|
|
243
300
|
end
|
244
301
|
end
|
245
302
|
|
303
|
+
class QuotingTestList < ActsAsListTestCase
|
304
|
+
include Shared::Quoting
|
305
|
+
|
306
|
+
def setup
|
307
|
+
setup_db_with_default
|
308
|
+
super
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
246
312
|
class DefaultScopedTest < ActsAsListTestCase
|
247
313
|
def setup
|
248
314
|
setup_db
|
@@ -603,3 +669,82 @@ class MultipleListsArrayScopeTest < ActsAsListTestCase
|
|
603
669
|
assert_equal [1], ArrayScopeListMixin.where(:parent_id => 4, :parent_type => 'anything').order(:pos).map(&:pos)
|
604
670
|
end
|
605
671
|
end
|
672
|
+
|
673
|
+
class TouchTest < ActsAsListTestCase
|
674
|
+
def setup
|
675
|
+
setup_db
|
676
|
+
4.times { ListMixin.create! updated_at: yesterday }
|
677
|
+
end
|
678
|
+
|
679
|
+
def now
|
680
|
+
Time.now.utc
|
681
|
+
end
|
682
|
+
|
683
|
+
def yesterday
|
684
|
+
1.day.ago
|
685
|
+
end
|
686
|
+
|
687
|
+
def updated_ats
|
688
|
+
ListMixin.pluck(:updated_at)
|
689
|
+
end
|
690
|
+
|
691
|
+
def test_moving_item_lower_touches_self_and_lower_item
|
692
|
+
ListMixin.first.move_lower
|
693
|
+
updated_ats[0..1].each do |updated_at|
|
694
|
+
assert_in_delta updated_at, now, 1.second
|
695
|
+
end
|
696
|
+
updated_ats[2..3].each do |updated_at|
|
697
|
+
assert_in_delta updated_at, yesterday, 1.second
|
698
|
+
end
|
699
|
+
end
|
700
|
+
|
701
|
+
def test_moving_item_higher_touches_self_and_higher_item
|
702
|
+
ListMixin.all.second.move_higher
|
703
|
+
updated_ats[0..1].each do |updated_at|
|
704
|
+
assert_in_delta updated_at, now, 1.second
|
705
|
+
end
|
706
|
+
updated_ats[2..3].each do |updated_at|
|
707
|
+
assert_in_delta updated_at, yesterday, 1.second
|
708
|
+
end
|
709
|
+
end
|
710
|
+
|
711
|
+
def test_moving_item_to_bottom_touches_all_other_items
|
712
|
+
ListMixin.first.move_to_bottom
|
713
|
+
updated_ats.each do |updated_at|
|
714
|
+
assert_in_delta updated_at, now, 1.second
|
715
|
+
end
|
716
|
+
end
|
717
|
+
|
718
|
+
def test_moving_item_to_top_touches_all_other_items
|
719
|
+
ListMixin.last.move_to_top
|
720
|
+
updated_ats.each do |updated_at|
|
721
|
+
assert_in_delta updated_at, now, 1.second
|
722
|
+
end
|
723
|
+
end
|
724
|
+
|
725
|
+
def test_removing_item_touches_all_lower_items
|
726
|
+
ListMixin.all.third.remove_from_list
|
727
|
+
updated_ats[0..1].each do |updated_at|
|
728
|
+
assert_in_delta updated_at, yesterday, 1.second
|
729
|
+
end
|
730
|
+
updated_ats[2..2].each do |updated_at|
|
731
|
+
assert_in_delta updated_at, now, 1.second
|
732
|
+
end
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
class ActsAsListTopTest < ActsAsListTestCase
|
737
|
+
def setup
|
738
|
+
setup_db
|
739
|
+
end
|
740
|
+
|
741
|
+
def test_acts_as_list_top
|
742
|
+
assert_equal 1, TheBaseSubclass.new.acts_as_list_top
|
743
|
+
assert_equal 0, ZeroBasedMixin.new.acts_as_list_top
|
744
|
+
end
|
745
|
+
|
746
|
+
def test_class_acts_as_list_top
|
747
|
+
assert_equal 1, TheBaseSubclass.acts_as_list_top
|
748
|
+
assert_equal 0, ZeroBasedMixin.acts_as_list_top
|
749
|
+
end
|
750
|
+
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: 0.7.
|
4
|
+
version: 0.7.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
@@ -10,34 +10,34 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-08-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: '3.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
|
-
- -
|
26
|
+
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: '3.0'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: bundler
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
|
-
- -
|
33
|
+
- - ">="
|
34
34
|
- !ruby/object:Gem::Version
|
35
35
|
version: 1.0.0
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
|
-
- -
|
40
|
+
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: 1.0.0
|
43
43
|
description: This "acts_as" extension provides the capabilities for sorting and reordering
|
@@ -49,9 +49,9 @@ executables: []
|
|
49
49
|
extensions: []
|
50
50
|
extra_rdoc_files: []
|
51
51
|
files:
|
52
|
-
- .gemtest
|
53
|
-
- .gitignore
|
54
|
-
- .travis.yml
|
52
|
+
- ".gemtest"
|
53
|
+
- ".gitignore"
|
54
|
+
- ".travis.yml"
|
55
55
|
- Appraisals
|
56
56
|
- CHANGELOG.md
|
57
57
|
- Gemfile
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- gemfiles/rails_3_2.gemfile
|
63
63
|
- gemfiles/rails_4_1.gemfile
|
64
64
|
- gemfiles/rails_4_2.gemfile
|
65
|
+
- gemfiles/rails_5_0.gemfile
|
65
66
|
- init.rb
|
66
67
|
- lib/acts_as_list.rb
|
67
68
|
- lib/acts_as_list/active_record/acts/list.rb
|
@@ -72,8 +73,10 @@ files:
|
|
72
73
|
- test/shared_list.rb
|
73
74
|
- test/shared_list_sub.rb
|
74
75
|
- test/shared_no_addition.rb
|
76
|
+
- test/shared_quoting.rb
|
75
77
|
- test/shared_top_addition.rb
|
76
78
|
- test/shared_zero_based.rb
|
79
|
+
- test/test_joined_list.rb
|
77
80
|
- test/test_list.rb
|
78
81
|
homepage: http://github.com/swanandp/acts_as_list
|
79
82
|
licenses:
|
@@ -85,12 +88,12 @@ require_paths:
|
|
85
88
|
- lib
|
86
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
87
90
|
requirements:
|
88
|
-
- -
|
91
|
+
- - ">="
|
89
92
|
- !ruby/object:Gem::Version
|
90
93
|
version: 1.9.2
|
91
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
95
|
requirements:
|
93
|
-
- -
|
96
|
+
- - ">="
|
94
97
|
- !ruby/object:Gem::Version
|
95
98
|
version: '0'
|
96
99
|
requirements: []
|
@@ -107,6 +110,8 @@ test_files:
|
|
107
110
|
- test/shared_list.rb
|
108
111
|
- test/shared_list_sub.rb
|
109
112
|
- test/shared_no_addition.rb
|
113
|
+
- test/shared_quoting.rb
|
110
114
|
- test/shared_top_addition.rb
|
111
115
|
- test/shared_zero_based.rb
|
116
|
+
- test/test_joined_list.rb
|
112
117
|
- test/test_list.rb
|