application_seeds 0.3.0 → 0.4.0

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/CHANGELOG.md CHANGED
@@ -1,4 +1,11 @@
1
- v0.3.0, 2013-01-09
1
+ v0.4.0, 2014-02-09
2
+ ------------------
3
+
4
+ * Added support for nested/inheritable datasets
5
+ * Warn user if `ApplicationSeeds.config=` is called after `ApplicationSeeds.dataset=`
6
+
7
+
8
+ v0.3.0, 2014-01-09
2
9
  ------------------
3
10
 
4
11
  * Added support for Capistrano 3.x
data/README.md CHANGED
@@ -34,12 +34,12 @@ the YAML files into a gem. The gem should have the following directory
34
34
  structure:
35
35
 
36
36
  ```
37
- lib
38
- +-- seeds
39
- |-- seed_data_set_1
37
+ lib/
38
+ +-- seeds/
39
+ |-- seed_data_set_1/
40
40
  | |-- some_data.yml
41
41
  | +-- some_other_data.yml
42
- +-- seed_data_set_2
42
+ +-- seed_data_set_2/
43
43
  |-- some_data.yml
44
44
  +-- some_other_data.yml
45
45
  ```
@@ -63,11 +63,11 @@ be identical to what is described above in the "Via a gem" section, but the `lib
63
63
  diretory is not required.
64
64
 
65
65
  ```
66
- seeds
67
- |-- seed_data_set_1
66
+ seeds/
67
+ |-- seed_data_set_1/
68
68
  | |-- some_data.yml
69
69
  | +-- some_other_data.yml
70
- +-- seed_data_set_2
70
+ +-- seed_data_set_2/
71
71
  |-- some_data.yml
72
72
  +-- some_other_data.yml
73
73
  ```
@@ -160,6 +160,65 @@ Then, you can seed a remote database by running the following:
160
160
  bundle exec cap <environment> deploy:application_seeds -s dataset=your_data_set
161
161
 
162
162
 
163
+ ## The Datasets
164
+
165
+ The `application_seeds` library supports multiple datasets within the
166
+ same source (place on the file system, gem, etc). The user specifies
167
+ which dataset to load when beginning to work with the seed data.
168
+
169
+ ApplicationSeeds.dataset = "my_data_set"
170
+
171
+ ### Nested Datasets
172
+
173
+ Datasets can be structured so that child directories can inherit the
174
+ seed data files that are stored in the parent directories. For example,
175
+ let's look at the following directory structure:
176
+
177
+ ```
178
+ seeds/
179
+ +-- parent_data_set/
180
+ |-- companies.yml
181
+ +-- child_data_set/
182
+ |-- departments.yml
183
+ +-- grandchild_data_set/
184
+ +-- people.yml
185
+ ```
186
+
187
+ In this example, if the `grandchild_data_set` is loaded, you will have
188
+ access to the seed data files in `grandchild_data_set`,
189
+ `child_data_set`, and `parent_data_set`. Because of this, data from
190
+ `people.yml`, `departments.yml`, and `companies.yml` can be loaded.
191
+
192
+ If `child_data_set` is loaded, you will have access to the seed data
193
+ files in `child_data_set` and `parent_data_set`, but **not**
194
+ `grandchild_data_set`. This includes the `departments.yml` and
195
+ `companies.yml` data files.
196
+
197
+ ### Merging Data Files
198
+
199
+ It is possible to have files for the same data type scattered throughout
200
+ the dataset hierarchy.
201
+
202
+ ```
203
+ seeds/
204
+ +-- parent_data_set/
205
+ |-- companies.yml
206
+ |-- people.yml
207
+ +-- child_data_set/
208
+ |-- departments.yml
209
+ |-- people.yml
210
+ +-- grandchild_data_set/
211
+ +-- people.yml
212
+ ```
213
+
214
+ In this example, when data is loaded from the `people` dataset via call
215
+ to `ApplicationSeeds.people`, then the result will contain the data from
216
+ all three files.
217
+
218
+ If the files contain conflicting labels, then precedence is given to
219
+ data at the lowest level (`grandchild_data_set` in this example).
220
+
221
+
163
222
  ## The Seed Files
164
223
 
165
224
  The seed files contain the data that the Rake task works with to
@@ -86,6 +86,7 @@ module ApplicationSeeds
86
86
  # Specify any configuration, such as the type of ids to generate (:integer or :uuid).
87
87
  #
88
88
  def config=(config)
89
+ warn "WARNING! Calling ApplicationSeeds.config= after dataset has been set (ApplicationSeeds.dataset=) may not produce expected results." unless @dataset.nil?
89
90
  @_config = config
90
91
  end
91
92
 
@@ -140,8 +141,8 @@ module ApplicationSeeds
140
141
  # the dataset could not be found.
141
142
  #
142
143
  def dataset=(dataset)
143
- if dataset.nil? || dataset.strip.empty? || !Dir.exist?(File.join(seed_data_path, dataset))
144
- datasets = Dir[File.join(seed_data_path, "*")].map { |x| File.basename(x) }.join(', ')
144
+ if dataset.nil? || dataset.strip.empty? || dataset_path(dataset).nil?
145
+ datasets = Dir[File.join(seed_data_path, "**", "*")].select { |x| File.directory?(x) }.map { |x| File.basename(x) }.join(', ')
145
146
 
146
147
  error_message = "\nERROR: A valid dataset is required!\n"
147
148
  error_message << "Usage: bundle exec rake application_seeds:load[your_data_set]\n\n"
@@ -150,6 +151,7 @@ module ApplicationSeeds
150
151
  end
151
152
 
152
153
  store_dataset(dataset)
154
+ find_seed_data_files(dataset)
153
155
  process_labels(dataset)
154
156
  load_seed_data(dataset)
155
157
  @dataset = dataset
@@ -241,14 +243,19 @@ module ApplicationSeeds
241
243
 
242
244
  def load_seed_data(dataset)
243
245
  @seed_data = {}
244
- seed_files(dataset).each do |seed_file|
246
+ @seed_data_files.each do |seed_file|
245
247
  basename = File.basename(seed_file, ".yml")
246
248
  data = YAML.load(ERB.new(File.read(seed_file)).result)
247
249
  if data
248
250
  data.each do |label, attributes|
249
251
  data[label] = replace_labels_with_ids(attributes)
250
252
  end
251
- @seed_data[basename] = data
253
+
254
+ if @seed_data[basename].nil?
255
+ @seed_data[basename] = data
256
+ else
257
+ @seed_data[basename] = data.merge(@seed_data[basename])
258
+ end
252
259
  end
253
260
  end
254
261
  end
@@ -313,6 +320,10 @@ module ApplicationSeeds
313
320
  end
314
321
  end
315
322
 
323
+ def dataset_path(dataset)
324
+ Dir[File.join(seed_data_path, "**", "*")].select { |x| File.directory?(x) && File.basename(x) == dataset }.first
325
+ end
326
+
316
327
  def fetch(type, &block)
317
328
  result = {}
318
329
  @seed_data[type].each do |label, attrs|
@@ -350,11 +361,20 @@ module ApplicationSeeds
350
361
  Database.connection.exec("INSERT INTO application_seeds (dataset) VALUES ('#{dataset}');")
351
362
  end
352
363
 
364
+ def find_seed_data_files(dataset)
365
+ @seed_data_files = []
366
+ path = dataset_path(dataset)
367
+ while (seed_data_path != path) do
368
+ @seed_data_files.concat(Dir[File.join(path, "*.yml")])
369
+ path.sub!(/\/[^\/]+$/, "")
370
+ end
371
+ end
372
+
353
373
  def process_labels(dataset)
354
374
  return @seed_labels unless @seed_labels.nil?
355
375
 
356
376
  @seed_labels = {}
357
- seed_files(dataset).each do |seed_file|
377
+ @seed_data_files.each do |seed_file|
358
378
  seed_type = File.basename(seed_file, ".yml")
359
379
  @seed_labels[seed_type] = {}
360
380
 
@@ -379,10 +399,6 @@ module ApplicationSeeds
379
399
  { :integer => id, :uuid => "00000000-0000-0000-0000-%012d" % id }
380
400
  end
381
401
 
382
- def seed_files(dataset)
383
- Dir[File.join(seed_data_path, dataset, "*.yml")]
384
- end
385
-
386
402
  def id_type(type)
387
403
  self.config["#{type}_id_type".to_sym] || self.config[:id_type]
388
404
  end
@@ -1,3 +1,3 @@
1
1
  module ApplicationSeeds
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -9,6 +9,24 @@ class Person
9
9
  end
10
10
  end
11
11
 
12
+ class Company
13
+ attr_accessor :attributes, :id, :saved
14
+ attr_accessor :name
15
+
16
+ def save!(options={})
17
+ @saved = true
18
+ end
19
+ end
20
+
21
+ class Department
22
+ attr_accessor :attributes, :id, :saved
23
+ attr_accessor :name
24
+
25
+ def save!(options={})
26
+ @saved = true
27
+ end
28
+ end
29
+
12
30
  describe "ApplicationSeeds" do
13
31
  before do
14
32
  ApplicationSeeds.data_directory = File.join(File.dirname(__FILE__), "seed_data")
@@ -219,8 +237,44 @@ describe "ApplicationSeeds" do
219
237
  end
220
238
  end
221
239
 
240
+ describe "with a nested dataset" do
241
+ before do
242
+ ApplicationSeeds.stub(:store_dataset)
243
+ ApplicationSeeds.dataset = "level_3"
244
+ end
245
+
246
+ describe "finding seed data" do
247
+ it "can find data at the root level" do
248
+ company = ApplicationSeeds.companies(:mega_corp)
249
+ expect(company['name']).to eql("Megacorp")
250
+ end
251
+ it "can find data at the middle level" do
252
+ department = ApplicationSeeds.departments(:engineering)
253
+ expect(department['name']).to eql("Engineering")
254
+ end
255
+ it "can find data at the lowest level" do
256
+ person = ApplicationSeeds.people(:joe_smith)
257
+ expect(person['first_name']).to eql("Joe")
258
+ end
259
+ end
260
+
261
+ describe "merging seed data" do
262
+ it "can merge data from different levels" do
263
+ person = ApplicationSeeds.people(:joe_smith)
264
+ expect(person['first_name']).to eql("Joe")
265
+ person = ApplicationSeeds.people(:sam_jones)
266
+ expect(person['first_name']).to eql("Sam")
267
+ end
268
+ it "gives the data in lower levels precendence" do
269
+ person = ApplicationSeeds.people(:ken_adams)
270
+ expect(person['first_name']).to eql("Ken")
271
+ end
272
+ end
273
+ end
274
+
222
275
  describe "with UUIDs configured for all seed types" do
223
276
  before do
277
+ ApplicationSeeds.instance_variable_set("@dataset", nil)
224
278
  ApplicationSeeds.stub(:store_dataset)
225
279
  ApplicationSeeds.config = { :id_type => :uuid }
226
280
  ApplicationSeeds.dataset = "test_data_set"
@@ -239,6 +293,7 @@ describe "ApplicationSeeds" do
239
293
 
240
294
  describe "with data type specific key types configured" do
241
295
  before do
296
+ ApplicationSeeds.instance_variable_set("@dataset", nil)
242
297
  ApplicationSeeds.stub(:store_dataset)
243
298
  ApplicationSeeds.config = { :id_type => :uuid, :companies_id_type => :integer }
244
299
  ApplicationSeeds.dataset = "test_data_set"
@@ -0,0 +1,9 @@
1
+ mega_corp:
2
+ name: Megacorp
3
+
4
+ ma_and_pa:
5
+ name: Ma and Pa
6
+
7
+ global_corp:
8
+ id: 123
9
+ name: Global Corp
@@ -0,0 +1,7 @@
1
+ engineering:
2
+ name: Engineering
3
+ people_ids: [joe_smith, jane_doe, john_walsh]
4
+
5
+ sales:
6
+ name: Sales
7
+ employee_ids: "[sam_jones, ken_adams] (people)"
@@ -0,0 +1,26 @@
1
+ joe_smith:
2
+ first_name: Joe
3
+ last_name: Smith
4
+ company_id: mega_corp
5
+ start_date: <%= 2.months.ago.to_date %>
6
+ bogus_attribute: foo
7
+
8
+ jane_doe:
9
+ first_name: Jane
10
+ last_name: Doe
11
+ company_id: mega_corp
12
+ start_date: <%= 10.months.ago.to_date %>
13
+ bogus_attribute: foo
14
+
15
+ john_walsh:
16
+ first_name: John
17
+ last_name: Walsh
18
+ company_id: ma_and_pa
19
+ start_date: <%= 10.years.ago.to_date %>
20
+ bogus_attribute: foo
21
+
22
+ ken_adams:
23
+ first_name: Ken
24
+ last_name: Adams
25
+ employer_id: ma_and_pa (companies)
26
+ start_date: <%= 10.years.ago.to_date %>
@@ -0,0 +1,12 @@
1
+ sam_jones:
2
+ id: 456
3
+ first_name: Sam
4
+ last_name: Jones
5
+ company_id: 123
6
+ start_date: <%= 10.years.ago.to_date %>
7
+
8
+ ken_adams:
9
+ first_name: Kenneth
10
+ last_name: Adams
11
+ employer_id: ma_and_pa (companies)
12
+ start_date: <%= 10.years.ago.to_date %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: application_seeds
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-09 00:00:00.000000000 Z
12
+ date: 2014-02-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -101,6 +101,10 @@ files:
101
101
  - spec/seed_data/test_data_set/companies.yml
102
102
  - spec/seed_data/test_data_set/departments.yml
103
103
  - spec/seed_data/test_data_set/people.yml
104
+ - spec/seed_data/test_inheritable_data_set/companies.yml
105
+ - spec/seed_data/test_inheritable_data_set/level_2/departments.yml
106
+ - spec/seed_data/test_inheritable_data_set/level_2/level_3/people.yml
107
+ - spec/seed_data/test_inheritable_data_set/level_2/people.yml
104
108
  homepage: https://github.com/centro/application_seeds
105
109
  licenses:
106
110
  - MIT
@@ -116,7 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
120
  version: '0'
117
121
  segments:
118
122
  - 0
119
- hash: 1780168384698824643
123
+ hash: 1911143344573555233
120
124
  required_rubygems_version: !ruby/object:Gem::Requirement
121
125
  none: false
122
126
  requirements:
@@ -125,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
129
  version: '0'
126
130
  segments:
127
131
  - 0
128
- hash: 1780168384698824643
132
+ hash: 1911143344573555233
129
133
  requirements: []
130
134
  rubyforge_project:
131
135
  rubygems_version: 1.8.23
@@ -139,3 +143,7 @@ test_files:
139
143
  - spec/seed_data/test_data_set/companies.yml
140
144
  - spec/seed_data/test_data_set/departments.yml
141
145
  - spec/seed_data/test_data_set/people.yml
146
+ - spec/seed_data/test_inheritable_data_set/companies.yml
147
+ - spec/seed_data/test_inheritable_data_set/level_2/departments.yml
148
+ - spec/seed_data/test_inheritable_data_set/level_2/level_3/people.yml
149
+ - spec/seed_data/test_inheritable_data_set/level_2/people.yml