closure_tree 3.8.0 → 3.8.1

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.
data/README.md CHANGED
@@ -425,6 +425,10 @@ Parallelism is not tested with Rails 3.0.x nor 3.1.x due to this
425
425
 
426
426
  ## Change log
427
427
 
428
+ ### 3.8.1
429
+
430
+ * Double-check locking for find_or_create_by_path
431
+
428
432
  ### 3.8.0
429
433
 
430
434
  * Support for preordered descendants. This requires a numeric sort order column.
@@ -133,21 +133,23 @@ module ClosureTree
133
133
  end
134
134
 
135
135
  # Find a child node whose +ancestry_path+ minus self.ancestry_path is +path+
136
- def find_or_create_by_path(path, attributes = {})
137
- ct_with_advisory_lock do
138
- subpath = path.is_a?(Enumerable) ? path.dup : [path]
139
- child_name = subpath.shift
140
- return self unless child_name
141
- child = transaction do
142
- attrs = {name_sym => child_name}
143
- attrs[:type] = self.type if ct_subclass? && ct_has_type?
144
- self.children.where(attrs).first || begin
145
- child = self.class.new(attributes.merge(attrs))
146
- self.children << child
147
- child
136
+ def find_or_create_by_path(path, attributes = {}, find_before_lock = true)
137
+ (find_before_lock && find_by_path(path)) || begin
138
+ ct_with_advisory_lock do
139
+ subpath = path.is_a?(Enumerable) ? path.dup : [path]
140
+ child_name = subpath.shift
141
+ return self unless child_name
142
+ child = transaction do
143
+ attrs = {name_sym => child_name}
144
+ attrs[:type] = self.type if ct_subclass? && ct_has_type?
145
+ self.children.where(attrs).first || begin
146
+ child = self.class.new(attributes.merge(attrs))
147
+ self.children << child
148
+ child
149
+ end
148
150
  end
151
+ child.find_or_create_by_path(subpath, attributes, false)
149
152
  end
150
- child.find_or_create_by_path(subpath, attributes)
151
153
  end
152
154
  end
153
155
 
@@ -327,14 +329,16 @@ module ClosureTree
327
329
 
328
330
  # Find or create nodes such that the +ancestry_path+ is +path+
329
331
  def find_or_create_by_path(path, attributes = {})
330
- subpath = path.dup
331
- root_name = subpath.shift
332
- ct_with_advisory_lock do
333
- # shenanigans because find_or_create can't infer we want the same class as this:
334
- # Note that roots will already be constrained to this subclass (in the case of polymorphism):
335
- root = roots.where(name_sym => root_name).first
336
- root ||= create!(attributes.merge(name_sym => root_name))
337
- root.find_or_create_by_path(subpath, attributes)
332
+ find_by_path(path) || begin
333
+ subpath = path.dup
334
+ root_name = subpath.shift
335
+ ct_with_advisory_lock do
336
+ # shenanigans because find_or_create can't infer we want the same class as this:
337
+ # Note that roots will already be constrained to this subclass (in the case of polymorphism):
338
+ root = roots.where(name_sym => root_name).first
339
+ root ||= create!(attributes.merge(name_sym => root_name))
340
+ root.find_or_create_by_path(subpath, attributes)
341
+ end
338
342
  end
339
343
  end
340
344
 
@@ -1,3 +1,3 @@
1
1
  module ClosureTree
2
- VERSION = "3.8.0" unless defined?(::ClosureTree::VERSION)
2
+ VERSION = "3.8.1" unless defined?(::ClosureTree::VERSION)
3
3
  end
metadata CHANGED
@@ -1,205 +1,215 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: closure_tree
3
- version: !ruby/object:Gem::Version
4
- hash: 39
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.8.1
5
5
  prerelease:
6
- segments:
7
- - 3
8
- - 8
9
- - 0
10
- version: 3.8.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Matthew McEachen
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2013-02-23 00:00:00 -08:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- requirement: &id001 !ruby/object:Gem::Requirement
12
+ date: 2013-02-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
23
17
  none: false
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- hash: 7
28
- segments:
29
- - 3
30
- - 0
31
- - 0
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
32
21
  version: 3.0.0
33
- version_requirements: *id001
34
- name: activerecord
35
- prerelease: false
36
22
  type: :runtime
37
- - !ruby/object:Gem::Dependency
38
- requirement: &id002 !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
39
25
  none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 19
44
- segments:
45
- - 0
46
- - 0
47
- - 6
48
- version: 0.0.6
49
- version_requirements: *id002
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.0.0
30
+ - !ruby/object:Gem::Dependency
50
31
  name: with_advisory_lock
51
- prerelease: false
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.0.6
52
38
  type: :runtime
53
- - !ruby/object:Gem::Dependency
54
- requirement: &id003 !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
55
41
  none: false
56
- requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- hash: 3
60
- segments:
61
- - 0
62
- version: "0"
63
- version_requirements: *id003
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.0.6
46
+ - !ruby/object:Gem::Dependency
64
47
  name: rake
65
- prerelease: false
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
66
54
  type: :development
67
- - !ruby/object:Gem::Dependency
68
- requirement: &id004 !ruby/object:Gem::Requirement
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
69
57
  none: false
70
- requirements:
71
- - - ">="
72
- - !ruby/object:Gem::Version
73
- hash: 3
74
- segments:
75
- - 0
76
- version: "0"
77
- version_requirements: *id004
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
78
63
  name: yard
79
- prerelease: false
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
80
70
  type: :development
81
- - !ruby/object:Gem::Dependency
82
- requirement: &id005 !ruby/object:Gem::Requirement
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
83
73
  none: false
84
- requirements:
85
- - - ">="
86
- - !ruby/object:Gem::Version
87
- hash: 3
88
- segments:
89
- - 0
90
- version: "0"
91
- version_requirements: *id005
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
92
79
  name: rspec
93
- prerelease: false
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
94
86
  type: :development
95
- - !ruby/object:Gem::Dependency
96
- requirement: &id006 !ruby/object:Gem::Requirement
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
97
89
  none: false
98
- requirements:
99
- - - ">="
100
- - !ruby/object:Gem::Version
101
- hash: 3
102
- segments:
103
- - 0
104
- version: "0"
105
- version_requirements: *id006
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
106
95
  name: rails
107
- prerelease: false
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
108
102
  type: :development
109
- - !ruby/object:Gem::Dependency
110
- requirement: &id007 !ruby/object:Gem::Requirement
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
111
105
  none: false
112
- requirements:
113
- - - ">="
114
- - !ruby/object:Gem::Version
115
- hash: 3
116
- segments:
117
- - 0
118
- version: "0"
119
- version_requirements: *id007
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
120
111
  name: rspec-rails
121
- prerelease: false
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
122
118
  type: :development
123
- - !ruby/object:Gem::Dependency
124
- requirement: &id008 !ruby/object:Gem::Requirement
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
125
121
  none: false
126
- requirements:
127
- - - ">="
128
- - !ruby/object:Gem::Version
129
- hash: 3
130
- segments:
131
- - 0
132
- version: "0"
133
- version_requirements: *id008
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
134
127
  name: mysql2
135
- prerelease: false
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
136
134
  type: :development
137
- - !ruby/object:Gem::Dependency
138
- requirement: &id009 !ruby/object:Gem::Requirement
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
139
137
  none: false
140
- requirements:
141
- - - ">="
142
- - !ruby/object:Gem::Version
143
- hash: 3
144
- segments:
145
- - 0
146
- version: "0"
147
- version_requirements: *id009
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
148
143
  name: pg
149
- prerelease: false
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
150
  type: :development
151
- - !ruby/object:Gem::Dependency
152
- requirement: &id010 !ruby/object:Gem::Requirement
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
153
  none: false
154
- requirements:
155
- - - ">="
156
- - !ruby/object:Gem::Version
157
- hash: 3
158
- segments:
159
- - 0
160
- version: "0"
161
- version_requirements: *id010
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
162
159
  name: sqlite3
163
- prerelease: false
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
164
166
  type: :development
165
- - !ruby/object:Gem::Dependency
166
- requirement: &id011 !ruby/object:Gem::Requirement
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
167
169
  none: false
168
- requirements:
169
- - - ">="
170
- - !ruby/object:Gem::Version
171
- hash: 3
172
- segments:
173
- - 0
174
- version: "0"
175
- version_requirements: *id011
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ - !ruby/object:Gem::Dependency
176
175
  name: uuidtools
177
- prerelease: false
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
178
182
  type: :development
179
- - !ruby/object:Gem::Dependency
180
- requirement: &id012 !ruby/object:Gem::Requirement
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
181
185
  none: false
182
- requirements:
183
- - - ">="
184
- - !ruby/object:Gem::Version
185
- hash: 3
186
- segments:
187
- - 0
188
- version: "0"
189
- version_requirements: *id012
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ - !ruby/object:Gem::Dependency
190
191
  name: strong_parameters
191
- prerelease: false
192
+ requirement: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
192
198
  type: :development
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ! '>='
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
193
206
  description: Easily and efficiently make your ActiveRecord model support hierarchies
194
- email:
207
+ email:
195
208
  - matthew-github@mceachen.org
196
209
  executables: []
197
-
198
210
  extensions: []
199
-
200
211
  extra_rdoc_files: []
201
-
202
- files:
212
+ files:
203
213
  - lib/closure_tree/acts_as_tree.rb
204
214
  - lib/closure_tree/columns.rb
205
215
  - lib/closure_tree/deterministic_ordering.rb
@@ -224,41 +234,37 @@ files:
224
234
  - spec/support/models.rb
225
235
  - spec/tag_spec.rb
226
236
  - spec/user_spec.rb
227
- has_rdoc: true
228
237
  homepage: http://matthew.mceachen.us/closure_tree
229
238
  licenses: []
230
-
231
239
  post_install_message:
232
240
  rdoc_options: []
233
-
234
- require_paths:
241
+ require_paths:
235
242
  - lib
236
- required_ruby_version: !ruby/object:Gem::Requirement
243
+ required_ruby_version: !ruby/object:Gem::Requirement
237
244
  none: false
238
- requirements:
239
- - - ">="
240
- - !ruby/object:Gem::Version
241
- hash: 3
242
- segments:
245
+ requirements:
246
+ - - ! '>='
247
+ - !ruby/object:Gem::Version
248
+ version: '0'
249
+ segments:
243
250
  - 0
244
- version: "0"
245
- required_rubygems_version: !ruby/object:Gem::Requirement
251
+ hash: -3183043301926645290
252
+ required_rubygems_version: !ruby/object:Gem::Requirement
246
253
  none: false
247
- requirements:
248
- - - ">="
249
- - !ruby/object:Gem::Version
250
- hash: 3
251
- segments:
254
+ requirements:
255
+ - - ! '>='
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ segments:
252
259
  - 0
253
- version: "0"
260
+ hash: -3183043301926645290
254
261
  requirements: []
255
-
256
262
  rubyforge_project:
257
- rubygems_version: 1.6.2
263
+ rubygems_version: 1.8.23
258
264
  signing_key:
259
265
  specification_version: 3
260
266
  summary: Easily and efficiently make your ActiveRecord model support hierarchies
261
- test_files:
267
+ test_files:
262
268
  - spec/cuisine_type_spec.rb
263
269
  - spec/db/database.yml
264
270
  - spec/db/schema.rb
@@ -272,3 +278,4 @@ test_files:
272
278
  - spec/support/models.rb
273
279
  - spec/tag_spec.rb
274
280
  - spec/user_spec.rb
281
+ has_rdoc: