application_seeds 0.0.1 → 0.1.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/CHANGELOG.md +12 -0
- data/LICENSE +21 -0
- data/README.md +69 -10
- data/Rakefile +5 -0
- data/application_seeds.gemspec +1 -0
- data/lib/application_seeds/attributes.rb +2 -2
- data/lib/application_seeds/database.rb +3 -0
- data/lib/application_seeds/version.rb +1 -1
- data/lib/application_seeds.rb +6 -3
- data/spec/application_seeds_spec.rb +83 -0
- data/spec/attributes_spec.rb +45 -0
- data/spec/seed_data/test_data_set/people.yml +3 -0
- metadata +10 -5
data/CHANGELOG.md
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2013 John Wood
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -6,33 +6,93 @@ in a non-production environment.
|
|
6
6
|
|
7
7
|
## Requirements
|
8
8
|
|
9
|
-
*
|
10
|
-
database
|
9
|
+
* Rails
|
10
|
+
* Postgresql (This library currently only works with the Postgresql database)
|
11
11
|
|
12
12
|
|
13
13
|
## Usage
|
14
14
|
|
15
15
|
#### Include the gem in your Gemfile
|
16
16
|
|
17
|
-
group :development
|
17
|
+
group :development do
|
18
18
|
gem 'application_seeds', :git => 'git@github.com:centro/application_seeds.git'
|
19
19
|
end
|
20
20
|
|
21
|
+
You should add this gem to any environment group that would need access
|
22
|
+
to the seed data (like an "integration" environment, for example).
|
23
|
+
|
24
|
+
|
25
|
+
#### Create a shared data set
|
26
|
+
|
27
|
+
This library operates on a set of YAML files that represent your shared
|
28
|
+
data set. The dataset can be provided two different ways.
|
29
|
+
|
30
|
+
##### Via a gem
|
31
|
+
|
32
|
+
In order to easily share the seed data between apps, you can package
|
33
|
+
the YAML files into a gem. The gem should have the following directory
|
34
|
+
structure:
|
35
|
+
|
36
|
+
```
|
37
|
+
lib
|
38
|
+
+-- seeds
|
39
|
+
|-- seed_data_set_1
|
40
|
+
| |-- some_data.yml
|
41
|
+
| +-- some_other_data.yml
|
42
|
+
+-- seed_data_set_2
|
43
|
+
|-- some_data.yml
|
44
|
+
+-- some_other_data.yml
|
45
|
+
```
|
46
|
+
|
47
|
+
The gem may contain any number of datasets. The above example has two datasets,
|
48
|
+
`seed_data_set_1` and `seed_data_set_2`. The YAML files are located in the
|
49
|
+
dataset directories.
|
50
|
+
|
51
|
+
You will need to include the gem containing your seed data in your `Gemfile`.
|
52
|
+
|
53
|
+
Use the `data_gem_name` API method to specify where your seed data is located.
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
ApplicationSeeds.data_gem_name = "my-seed-data-gem"
|
57
|
+
```
|
58
|
+
|
59
|
+
##### Via the filesystem
|
60
|
+
|
61
|
+
The dataset may also exist on the filesystem. The directory structure should
|
62
|
+
be identical to what is described above in the "Via a gem" section, but the `lib`
|
63
|
+
diretory is not required.
|
64
|
+
|
65
|
+
```
|
66
|
+
seeds
|
67
|
+
|-- seed_data_set_1
|
68
|
+
| |-- some_data.yml
|
69
|
+
| +-- some_other_data.yml
|
70
|
+
+-- seed_data_set_2
|
71
|
+
|-- some_data.yml
|
72
|
+
+-- some_other_data.yml
|
73
|
+
```
|
74
|
+
|
75
|
+
Use the `data_directory` API method to specify the path to your seed data on the filesystem.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
ApplicationSeeds.data_directory = "/path/to/seeds"
|
79
|
+
```
|
21
80
|
|
22
81
|
#### Create a rake task to create data model objects from the seed data
|
23
82
|
|
24
|
-
**The application** needs to create objects from the common seed data.
|
25
|
-
do this,
|
26
|
-
below) that reads the seed data, and uses it to create the objects in
|
83
|
+
**The application** needs to create objects from the common seed data. To
|
84
|
+
do this, you will need to create a Rake task (such as the one
|
85
|
+
below) for your application that reads the seed data, and uses it to create the objects in
|
27
86
|
the application's own data model.
|
28
87
|
|
29
88
|
`ApplicationSeeds` provides an API to allow for the easy retrieveal of
|
30
|
-
seed data. See
|
89
|
+
seed data. See below for more information about the API.
|
31
90
|
|
32
91
|
```ruby
|
33
92
|
namespace :application_seeds do
|
34
93
|
desc 'Dump the development database and load it with standardized application seed data'
|
35
94
|
task :load, [:dataset] => ['db:drop', 'db:create', 'db:migrate', :environment] do |t, args|
|
95
|
+
ApplicationSeeds.data_gem_name = "my-seed-data-gem"
|
36
96
|
ApplicationSeeds.dataset = args[:dataset]
|
37
97
|
|
38
98
|
seed_campaigns
|
@@ -160,7 +220,7 @@ does not.
|
|
160
220
|
```ruby
|
161
221
|
ApplicationSeeds.campaigns # where "campaigns" is the name of the seed file
|
162
222
|
```
|
163
|
-
|
223
|
+
|
164
224
|
This call returns a hash with one or more entries (depending on the contentes of the seed file).
|
165
225
|
The IDs of the object are the keys, and a hash containing the object's attributes are the values.
|
166
226
|
An exception is raised if no seed data could be with the given name.
|
@@ -260,7 +320,7 @@ another application, the key specified by the client must be in the server's
|
|
260
320
|
data set, along with the other data associated with the key that the
|
261
321
|
client is requesting.
|
262
322
|
|
263
|
-
Often, each application will have its own,
|
323
|
+
Often, each application will have its own, siloed seed data, making
|
264
324
|
inter-app communication impossible. In order to get all of the
|
265
325
|
application data in sync, developers will often resort to populating
|
266
326
|
their development databases with production data. Production data on a
|
@@ -316,4 +376,3 @@ couple applications. The goal of a service oriented
|
|
316
376
|
architecture is to prevent this. With great power comes great
|
317
377
|
responsibility. Carefully consider the trade offs any time you
|
318
378
|
introduce an API call to fetch data from a remote service.
|
319
|
-
|
data/Rakefile
CHANGED
data/application_seeds.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.description = %q{A library for managing standardized application seed data}
|
12
12
|
gem.summary = %q{A library for managing a standardized set of seed data for applications in a non-production environment}
|
13
13
|
gem.homepage = "https://github.com/centro/application_seeds"
|
14
|
+
gem.license = 'MIT'
|
14
15
|
|
15
16
|
gem.files = `git ls-files`.split($/)
|
16
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -9,12 +9,12 @@ module ApplicationSeeds
|
|
9
9
|
|
10
10
|
def select_attributes(*attribute_names)
|
11
11
|
attribute_names.map!(&:to_s)
|
12
|
-
select { |k,v| attribute_names.include?(k) }
|
12
|
+
Attributes.new(select { |k,v| attribute_names.include?(k) })
|
13
13
|
end
|
14
14
|
|
15
15
|
def reject_attributes(*attribute_names)
|
16
16
|
attribute_names.map!(&:to_s)
|
17
|
-
reject { |k,v| attribute_names.include?(k) }
|
17
|
+
Attributes.new(reject { |k,v| attribute_names.include?(k) })
|
18
18
|
end
|
19
19
|
|
20
20
|
def map_attributes(mapping)
|
@@ -18,6 +18,9 @@ module ApplicationSeeds
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def create_metadata_table
|
21
|
+
if defined?(ActiveRecord)
|
22
|
+
ActiveRecord::SchemaDumper.ignore_tables = ["application_seeds"]
|
23
|
+
end
|
21
24
|
connection.exec('DROP TABLE IF EXISTS application_seeds;')
|
22
25
|
connection.exec('CREATE TABLE application_seeds (dataset varchar(255));')
|
23
26
|
end
|
data/lib/application_seeds.rb
CHANGED
@@ -126,9 +126,7 @@ module ApplicationSeeds
|
|
126
126
|
raise error_message
|
127
127
|
end
|
128
128
|
|
129
|
-
|
130
|
-
Database.connection.exec("INSERT INTO application_seeds (dataset) VALUES ('#{dataset}');")
|
131
|
-
|
129
|
+
store_dataset(dataset)
|
132
130
|
@dataset = dataset
|
133
131
|
end
|
134
132
|
|
@@ -251,5 +249,10 @@ module ApplicationSeeds
|
|
251
249
|
Attributes.new(data)
|
252
250
|
end
|
253
251
|
|
252
|
+
def store_dataset(dataset)
|
253
|
+
Database.create_metadata_table
|
254
|
+
Database.connection.exec("INSERT INTO application_seeds (dataset) VALUES ('#{dataset}');")
|
255
|
+
end
|
256
|
+
|
254
257
|
end
|
255
258
|
end
|
@@ -1,5 +1,14 @@
|
|
1
1
|
require 'application_seeds'
|
2
2
|
|
3
|
+
class Person
|
4
|
+
attr_accessor :attributes, :id, :saved
|
5
|
+
attr_accessor :first_name, :last_name, :company_id, :start_date
|
6
|
+
|
7
|
+
def save!(options={})
|
8
|
+
@saved = true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
3
12
|
describe "ApplicationSeeds" do
|
4
13
|
before do
|
5
14
|
ApplicationSeeds.data_directory = File.join(File.dirname(__FILE__), "seed_data")
|
@@ -80,4 +89,78 @@ describe "ApplicationSeeds" do
|
|
80
89
|
end
|
81
90
|
end
|
82
91
|
|
92
|
+
context "with a valid dataset" do
|
93
|
+
before do
|
94
|
+
ApplicationSeeds.stub(:store_dataset)
|
95
|
+
ApplicationSeeds.dataset = "test_data_set"
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#create_object" do
|
99
|
+
before do
|
100
|
+
@attributes = ApplicationSeeds.people(1)
|
101
|
+
@object = ApplicationSeeds.create_object!(Person, @attributes['id'], @attributes)
|
102
|
+
end
|
103
|
+
it "assigns the id" do
|
104
|
+
@object.id.should == 1
|
105
|
+
end
|
106
|
+
it "assigns the attributes" do
|
107
|
+
@object.attributes.should == @attributes.reject { |k,v| k == "bogus_attribute" }
|
108
|
+
end
|
109
|
+
it "saves the object in the database" do
|
110
|
+
@object.saved.should be_true
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "fetching all seed data" do
|
115
|
+
before do
|
116
|
+
@people = ApplicationSeeds.people
|
117
|
+
end
|
118
|
+
it "returns all people" do
|
119
|
+
@people.size.should == 3
|
120
|
+
end
|
121
|
+
it "returns the attributes for each person" do
|
122
|
+
person = @people[2]
|
123
|
+
person['first_name'].should == "Jane"
|
124
|
+
person['last_name'].should == "Doe"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "fetching seed data by id" do
|
129
|
+
it "returns the attributes for each person" do
|
130
|
+
@person = ApplicationSeeds.people(2)
|
131
|
+
@person['first_name'].should == "Jane"
|
132
|
+
@person['last_name'].should == "Doe"
|
133
|
+
end
|
134
|
+
it "raises an error if no data could be found with the specified id" do
|
135
|
+
expect { ApplicationSeeds.people(404) }.to raise_error(RuntimeError)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "fetching seed data by property values" do
|
140
|
+
it "returns the found person" do
|
141
|
+
@people = ApplicationSeeds.people(:last_name => 'Walsh', :company_id => 2)
|
142
|
+
@people.size.should == 1
|
143
|
+
@people.values.first['first_name'].should == "John"
|
144
|
+
@people.values.first['last_name'].should == "Walsh"
|
145
|
+
end
|
146
|
+
it "returns multiple people if there are multiple matches" do
|
147
|
+
@people = ApplicationSeeds.people(:company_id => 1)
|
148
|
+
@people.size.should == 2
|
149
|
+
@people.values.first['first_name'].should == "Joe"
|
150
|
+
@people.values.last['first_name'].should == "Jane"
|
151
|
+
end
|
152
|
+
it "returns an empty hash if no matches could be found" do
|
153
|
+
@people = ApplicationSeeds.people(:last_name => '404')
|
154
|
+
@people.should == {}
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "ERB" do
|
159
|
+
it "processes ERB snippets in the fixtures" do
|
160
|
+
@person = ApplicationSeeds.people(1)
|
161
|
+
@person['start_date'].should == 2.months.ago.to_date
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
83
166
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'application_seeds'
|
2
|
+
|
3
|
+
describe "Attributes" do
|
4
|
+
before do
|
5
|
+
@attributes = ApplicationSeeds::Attributes.new("first_name" => "Billy",
|
6
|
+
"last_name" => "Bob",
|
7
|
+
"occupation" => "Bus Driver")
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#select_attributes" do
|
11
|
+
before do
|
12
|
+
@selected_attributes = @attributes.select_attributes(:first_name, :occupation)
|
13
|
+
end
|
14
|
+
it "returns only the select attributes" do
|
15
|
+
@selected_attributes.should == { "first_name" => "Billy", "occupation" => "Bus Driver" }
|
16
|
+
end
|
17
|
+
it "returns a new instance of the Attributes class" do
|
18
|
+
@selected_attributes.is_a?(ApplicationSeeds::Attributes).should be_true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#reject_attributes" do
|
23
|
+
before do
|
24
|
+
@rejected_attributes = @attributes.reject_attributes(:first_name, :last_name)
|
25
|
+
end
|
26
|
+
it "returns only the select attributes" do
|
27
|
+
@rejected_attributes.should == { "occupation" => "Bus Driver" }
|
28
|
+
end
|
29
|
+
it "returns a new instance of the Attributes class" do
|
30
|
+
@rejected_attributes.is_a?(ApplicationSeeds::Attributes).should be_true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#map_attributes" do
|
35
|
+
before do
|
36
|
+
@mapped_attributes = @attributes.map_attributes(:first_name => :fname, :last_name => :lname)
|
37
|
+
end
|
38
|
+
it "returns only the select attributes" do
|
39
|
+
@mapped_attributes.should == { "fname" => "Billy", "lname" => "Bob", "occupation" => "Bus Driver" }
|
40
|
+
end
|
41
|
+
it "returns a new instance of the Attributes class" do
|
42
|
+
@mapped_attributes.is_a?(ApplicationSeeds::Attributes).should be_true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -3,16 +3,19 @@
|
|
3
3
|
last_name: Smith
|
4
4
|
company_id: 1
|
5
5
|
start_date: <%= 2.months.ago.to_date %>
|
6
|
+
bogus_attribute: foo
|
6
7
|
|
7
8
|
- id: 2
|
8
9
|
first_name: Jane
|
9
10
|
last_name: Doe
|
10
11
|
company_id: 1
|
11
12
|
start_date: <%= 10.months.ago.to_date %>
|
13
|
+
bogus_attribute: foo
|
12
14
|
|
13
15
|
- id: 3
|
14
16
|
first_name: John
|
15
17
|
last_name: Walsh
|
16
18
|
company_id: 2
|
17
19
|
start_date: <%= 10.years.ago.to_date %>
|
20
|
+
bogus_attribute: foo
|
18
21
|
|
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.
|
4
|
+
version: 0.1.1
|
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: 2013-
|
12
|
+
date: 2013-12-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -83,7 +83,9 @@ extensions: []
|
|
83
83
|
extra_rdoc_files: []
|
84
84
|
files:
|
85
85
|
- .gitignore
|
86
|
+
- CHANGELOG.md
|
86
87
|
- Gemfile
|
88
|
+
- LICENSE
|
87
89
|
- README.md
|
88
90
|
- Rakefile
|
89
91
|
- application_seeds.gemspec
|
@@ -93,9 +95,11 @@ files:
|
|
93
95
|
- lib/application_seeds/database.rb
|
94
96
|
- lib/application_seeds/version.rb
|
95
97
|
- spec/application_seeds_spec.rb
|
98
|
+
- spec/attributes_spec.rb
|
96
99
|
- spec/seed_data/test_data_set/people.yml
|
97
100
|
homepage: https://github.com/centro/application_seeds
|
98
|
-
licenses:
|
101
|
+
licenses:
|
102
|
+
- MIT
|
99
103
|
post_install_message:
|
100
104
|
rdoc_options: []
|
101
105
|
require_paths:
|
@@ -108,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
112
|
version: '0'
|
109
113
|
segments:
|
110
114
|
- 0
|
111
|
-
hash: -
|
115
|
+
hash: -2507870664277068952
|
112
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
117
|
none: false
|
114
118
|
requirements:
|
@@ -117,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
121
|
version: '0'
|
118
122
|
segments:
|
119
123
|
- 0
|
120
|
-
hash: -
|
124
|
+
hash: -2507870664277068952
|
121
125
|
requirements: []
|
122
126
|
rubyforge_project:
|
123
127
|
rubygems_version: 1.8.23
|
@@ -127,4 +131,5 @@ summary: A library for managing a standardized set of seed data for applications
|
|
127
131
|
a non-production environment
|
128
132
|
test_files:
|
129
133
|
- spec/application_seeds_spec.rb
|
134
|
+
- spec/attributes_spec.rb
|
130
135
|
- spec/seed_data/test_data_set/people.yml
|