closure_tree 3.8.0 → 3.8.1

Sign up to get free protection for your applications and to get access to all the features.
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: