planter 0.0.7 → 0.0.11
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.
- checksums.yaml +4 -4
- data/README.md +57 -37
- data/lib/generators/planter/initializer_generator.rb +33 -0
- data/lib/generators/planter/seeder_generator.rb +40 -0
- data/lib/planter/railtie.rb +8 -0
- data/lib/planter/seeder.rb +129 -18
- data/lib/planter/version.rb +1 -1
- data/lib/planter.rb +27 -72
- data/lib/tasks/planter_tasks.rake +13 -4
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9eab293e0cec74131351f8e1ff29919165da5e7eeb9cea2d305802f8cf5e1c8f
|
4
|
+
data.tar.gz: 6e06237482fb476e3a664fead3bfd64d15013f5570316964360161c9e05a25a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d28919333f86c7e0d6be6e4a12a4dea558ec0d734ccb63457931af6c8070f71ff76a90c370d2e26a8500106dbb81585ca9685b829c2cf220cd770be229e274d
|
7
|
+
data.tar.gz: a40e5e9ae771224e486c8263d2194fc5de1256b6d6a0d9d880ef44aea01294160fbbe1f139b74a375f4adb3e6372e155700968de0d862918ad0662ce3a2fc80c
|
data/README.md
CHANGED
@@ -7,23 +7,24 @@
|
|
7
7
|
|
8
8
|
Seeds for Rails applications can get complicated fast, and Rails doesn't provide
|
9
9
|
much for assisting with this process. This plugin seeks to rectify that by
|
10
|
-
providing easy ways to seed specific tables
|
11
|
-
db:seed` task.
|
10
|
+
providing easy ways to seed specific tables.
|
12
11
|
|
13
12
|
Features include:
|
14
13
|
|
15
14
|
- Seed tables from CSV files, an array of hashes, or custom methods.
|
16
|
-
- Call specific seeders with `rails
|
15
|
+
- Call specific seeders with `rails planter:seed SEEDERS=users,addresses`.
|
17
16
|
- Control the number of records being created.
|
18
17
|
- Seed associations.
|
19
18
|
|
20
19
|
You can view the documentation [here](https://evanthegrayt.github.io/planter/).
|
21
20
|
|
22
21
|
## Installation
|
23
|
-
Add
|
22
|
+
Add the following line to your application's Gemfile. Because this plugin is
|
23
|
+
currently a pre-release version, it's recommended to lock it to a specific
|
24
|
+
version, as breaking changes may occur, even at the patch level.
|
24
25
|
|
25
26
|
```ruby
|
26
|
-
gem 'planter'
|
27
|
+
gem 'planter', '0.0.10'
|
27
28
|
```
|
28
29
|
|
29
30
|
And then execute:
|
@@ -41,30 +42,69 @@ $ gem install planter
|
|
41
42
|
## Usage
|
42
43
|
Let's assume you'd like to seed your `users` table.
|
43
44
|
|
44
|
-
To get started,
|
45
|
-
|
46
|
-
the correct order to successfully seed the tables when considering associations.
|
45
|
+
To get started, run `rails generate planter:initializer`, which will create
|
46
|
+
`config/initializers/planter.rb` with the following contents.
|
47
47
|
|
48
48
|
```ruby
|
49
49
|
require 'planter'
|
50
50
|
|
51
51
|
Planter.configure do |config|
|
52
|
-
|
52
|
+
##
|
53
|
+
# The list of seeders. These files are stored in the
|
54
|
+
# config.seeders_directory, which can be changed below. When a new
|
55
|
+
# seeder is generated, it will be appended to the bottom of this
|
56
|
+
# list. If the order is incorrect, you'll need to adjust it.
|
57
|
+
# Just be sure to keep the ending bracket on its own line, or the
|
58
|
+
# generator won't know where to put new elements.
|
59
|
+
config.seeders = %i[
|
60
|
+
]
|
61
|
+
|
62
|
+
##
|
63
|
+
# The directory where the seeder files are kept.
|
64
|
+
# config.seeders_directory = 'db/seeds'
|
65
|
+
|
66
|
+
##
|
67
|
+
# The directory where CSVs are kept.
|
68
|
+
# config.csv_files_directory = 'db/seed_files'
|
53
69
|
end
|
70
|
+
```
|
71
|
+
|
72
|
+
By default, a `planter:seed` task is provided for seeding your application. This
|
73
|
+
allows you to use `db:seed` for other purposes. If you want Planter to hook
|
74
|
+
into the existing `db:seed` task, simply add the following to `db/seeds.rb`.
|
54
75
|
|
76
|
+
```ruby
|
55
77
|
Planter.seed
|
56
78
|
```
|
57
79
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
`
|
80
|
+
To create a users seeder, run `rails generate planter:seeder users`. Usually,
|
81
|
+
seeders seed a specific table, so it's recommended to name your seeders after
|
82
|
+
the table. If you don't, you'll need to manually specify a few things. More on
|
83
|
+
that later. This will create a file named `db/seeds/users_seeder.rb` (the
|
84
|
+
directory will be created if it doesn't exist) with the following contents.
|
62
85
|
|
63
86
|
```ruby
|
64
87
|
class UsersSeeder < Planter::Seeder
|
88
|
+
# TODO: Choose a seeding_method. For example:
|
89
|
+
# seeding_method :csv
|
90
|
+
|
91
|
+
# For now, we overload the seed method so no exception will be raised.
|
92
|
+
def seed
|
93
|
+
end
|
65
94
|
end
|
66
95
|
```
|
67
96
|
|
97
|
+
This also adds `users` to the `config.seeders` array in our initializer. A few
|
98
|
+
things to note.
|
99
|
+
|
100
|
+
- The seeder will always be appended at the end of the array. If this is not the
|
101
|
+
correct order, you'll need to adjust the array manually.
|
102
|
+
- When adjusting the array, always keep the closing bracket on its own line, or
|
103
|
+
the generator won't know where to put the new seeders.
|
104
|
+
|
105
|
+
If you want to generate a seeder for every table currently in your database, run
|
106
|
+
`rails generate planter:seeder ALL`.
|
107
|
+
|
68
108
|
You then need to choose a seeding method, of which there are currently three.
|
69
109
|
|
70
110
|
### Seeding from CSV
|
@@ -100,14 +140,14 @@ file name. For example, `users.csv.erb`. Note that lines starting with `<%` and
|
|
100
140
|
ending with `%>` will not be considered rows, so you can use `ERB` rows to set
|
101
141
|
values. For example:
|
102
142
|
|
103
|
-
```
|
143
|
+
```
|
104
144
|
email,login_attempts
|
105
145
|
<% count = 1 %>
|
106
146
|
test2@example.com,<%= count += 1 %>
|
107
147
|
test2@example.com,<%= count += 1 %>
|
108
148
|
```
|
109
149
|
|
110
|
-
Running `rails
|
150
|
+
Running `rails planter:seed` will now seed your `users` table.
|
111
151
|
|
112
152
|
## Seeding from a data array
|
113
153
|
If you need dynamic seeds, you can add something similar to the following to
|
@@ -115,7 +155,7 @@ your seeder class. In this example, we'll use
|
|
115
155
|
[faker](https://github.com/faker-ruby/faker).
|
116
156
|
|
117
157
|
```ruby
|
118
|
-
require 'faker' # You
|
158
|
+
require 'faker' # You could just require this in `db/seeds.rb`.
|
119
159
|
|
120
160
|
class UsersSeeder < Planter::Seeder
|
121
161
|
seeding_method :data_array, number_of_records: 10
|
@@ -135,7 +175,7 @@ ten elements to create ten records. It's also worth noting that setting an
|
|
135
175
|
instance variable called `@data` from an `initialize` method would also work, as
|
136
176
|
the `Planter::Seeder` parent class automatically provides `attr_reader :data`.
|
137
177
|
|
138
|
-
Running `rails
|
178
|
+
Running `rails planter:seed` should now seed your `users` table.
|
139
179
|
|
140
180
|
You can also seed children records for every existing record of a parent model.
|
141
181
|
For example, to seed an address for every user, you'd need to create an
|
@@ -180,26 +220,6 @@ class UsersSeeder < Planter::Seeder
|
|
180
220
|
end
|
181
221
|
```
|
182
222
|
|
183
|
-
## Customization
|
184
|
-
You can change the directories of both the seeder files and the CSV files. In
|
185
|
-
your `configure` block in `db/seeds.rb`, you can add the following. Note that,
|
186
|
-
in both instances, the path should be relative to `Rails.root`.
|
187
|
-
|
188
|
-
```ruby
|
189
|
-
require 'planter'
|
190
|
-
|
191
|
-
Planter.configure do |config|
|
192
|
-
config.seeders_directory = 'db/seeder_classes'
|
193
|
-
config.csv_files_directory = 'db/csvs'
|
194
|
-
config.seeders = %i[
|
195
|
-
users
|
196
|
-
addresses
|
197
|
-
]
|
198
|
-
end
|
199
|
-
|
200
|
-
Planter.seed
|
201
|
-
```
|
202
|
-
|
203
223
|
## License
|
204
224
|
The gem is available as open source under the terms of the [MIT
|
205
225
|
License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Planter
|
2
|
+
module Generators
|
3
|
+
class InitializerGenerator < Rails::Generators::Base
|
4
|
+
desc 'Genrates an initializer for Planter at config/initializers/planter.rb'
|
5
|
+
|
6
|
+
def create_initializer_file
|
7
|
+
create_file 'config/initializers/planter.rb', <<~EOF
|
8
|
+
require 'planter'
|
9
|
+
|
10
|
+
Planter.configure do |config|
|
11
|
+
##
|
12
|
+
# The list of seeders. These files are stored in the
|
13
|
+
# config.seeders_directory, which can be changed below. When a new
|
14
|
+
# seeder is generated, it will be appended to the bottom of this
|
15
|
+
# list. If the order is incorrect, you'll need to adjust it.
|
16
|
+
# Just be sure to keep the ending bracket on its own line, or the
|
17
|
+
# generator won't know where to put new elements.
|
18
|
+
config.seeders = %i[
|
19
|
+
]
|
20
|
+
|
21
|
+
##
|
22
|
+
# The directory where the seeder files are kept.
|
23
|
+
# config.seeders_directory = 'db/seeds'
|
24
|
+
|
25
|
+
##
|
26
|
+
# The directory where CSVs are kept.
|
27
|
+
# config.csv_files_directory = 'db/seed_files'
|
28
|
+
end
|
29
|
+
EOF
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Planter
|
2
|
+
module Generators
|
3
|
+
class SeederGenerator < Rails::Generators::Base
|
4
|
+
argument :seeder, required: true
|
5
|
+
|
6
|
+
desc "This generator creates a seeder file at #{::Planter.config.seeders_directory}"
|
7
|
+
|
8
|
+
def generate_seeders
|
9
|
+
seeder == 'ALL' ? tables.each { |t| generate(t) } : generate(seeder)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def generate(seeder)
|
15
|
+
empty_directory ::Planter.config.seeders_directory
|
16
|
+
|
17
|
+
create_file "#{::Planter.config.seeders_directory}/#{seeder}_seeder.rb", <<~EOF
|
18
|
+
class #{seeder.camelize}Seeder < Planter::Seeder
|
19
|
+
# TODO: Choose a seeding_method. For example:
|
20
|
+
# seeding_method :csv
|
21
|
+
|
22
|
+
# For now, we overload the seed method so no exception will be raised.
|
23
|
+
def seed
|
24
|
+
end
|
25
|
+
end
|
26
|
+
EOF
|
27
|
+
|
28
|
+
inject_into_file 'config/initializers/planter.rb',
|
29
|
+
" #{seeder}\n",
|
30
|
+
before: /^\s*\]\s*$/
|
31
|
+
end
|
32
|
+
|
33
|
+
def tables
|
34
|
+
@tables ||= ActiveRecord::Base.connection.tables.reject do |table|
|
35
|
+
%w[ar_internal_metadata schema_migrations].include?(table)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/planter/railtie.rb
CHANGED
data/lib/planter/seeder.rb
CHANGED
@@ -2,7 +2,88 @@
|
|
2
2
|
|
3
3
|
module Planter
|
4
4
|
##
|
5
|
-
#
|
5
|
+
# Class that seeders should inherit from. Seeder files should be in
|
6
|
+
# +db/seeds+, and named +TABLE_seeder.rb+, where +TABLE+ is the name of the
|
7
|
+
# table being seeded (I.E. +users_seeder.rb+). If your seeder is named
|
8
|
+
# differently than the table, you'll need to specify the table with the
|
9
|
+
# +model+ option. The seeder's class name should be the same as the file
|
10
|
+
# name, but camelized. So, +UsersSeeder+. The directory where the seeder
|
11
|
+
# files are located can be changed via an initializer.
|
12
|
+
#
|
13
|
+
# The most basic way to seed is to have a CSV file with the same name as the
|
14
|
+
# table in +db/seed_files/+. So, +users.csv+. This CSV should have the
|
15
|
+
# table's column names as header. To seed using this method, your class
|
16
|
+
# should look like the following. Note that +:csv_name+ and +:model+ are only
|
17
|
+
# required if your seeder or csv are named differently than the table being
|
18
|
+
# seeded. The directory where the seed files are kept can be changed via an
|
19
|
+
# initializer.
|
20
|
+
# # db/seeds/users_seeder.rb
|
21
|
+
# require 'planter'
|
22
|
+
# class UsersSeeder < Planter::Seeder
|
23
|
+
# seeding_method :csv, csv_name: :users, model: 'User'
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# Another way to seed is to create records from a data array. To do this,
|
27
|
+
# your class must implement a +data+ attribute or method, which is an array
|
28
|
+
# of hashes. Note that this class already provides the +attr_reader+ for this
|
29
|
+
# attribute, so the most you have to do it create instance variables in your
|
30
|
+
# constructor. If if you want your data to be different for each new record
|
31
|
+
# (via Faker, +Array#sample+, etc.), you'll probably want to supply a method
|
32
|
+
# called data that returns an array of new data each time.
|
33
|
+
# require 'planter'
|
34
|
+
# class UsersSeeder < Planter::Seeder
|
35
|
+
# seeding_method :data_array
|
36
|
+
# def data
|
37
|
+
# [{foo: 'bar', baz: 'bar'}]
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# In both of the above methods, you can specify +parent_model+ and
|
42
|
+
# +association+. If specified, records will be created via that parent
|
43
|
+
# model's association. If +association+ is not provided, it will be assumed
|
44
|
+
# to be the model name, pluralized and snake-cased (implying a +has_many+
|
45
|
+
# relationship). For example, if we're seeding the users table, and the
|
46
|
+
# model is +User+, the association will default to +users+.
|
47
|
+
# require 'planter'
|
48
|
+
# class UsersSeeder < Planter::Seeder
|
49
|
+
# seeding_method :data_array, parent_model: 'Person', association: :users
|
50
|
+
# def data
|
51
|
+
# [{foo: 'bar', baz: 'bar'}]
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# You can also set +number_of_records+ to determine how many times each
|
56
|
+
# record in the +data+ array will get created. The default is 1. Note that if
|
57
|
+
# this attribute is set alongside +parent_model+ and +association+,
|
58
|
+
# +number_of_records+ will be how many records will be created for each
|
59
|
+
# record in the parent table.
|
60
|
+
# require 'planter'
|
61
|
+
# class UsersSeeder < Planter::Seeder
|
62
|
+
# seeding_method :data_array, number_of_records: 5
|
63
|
+
# def data
|
64
|
+
# [{foo: 'bar', baz: 'bar'}]
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# By default, all fields are used to look up the record. If it already
|
69
|
+
# exists, it is not re-created. If you have specific fields that a record
|
70
|
+
# should be looked-up by, you can pass the +unique_columns+ option. This will
|
71
|
+
# attempt to look up the record by those fields only, and if one doesn't
|
72
|
+
# exist, one will be created with the rest of the attributes. An example of
|
73
|
+
# when this would be useful is with Devise; you can't pass +password+ in the
|
74
|
+
# create method, so specifying +unique_columns+ on everything except
|
75
|
+
# +password+ allows it to be passed as an attribute to the +first_or_create+
|
76
|
+
# call.
|
77
|
+
# require 'planter'
|
78
|
+
# class UsersSeeder < Planter::Seeder
|
79
|
+
# seeding_method :data_array, unique_columns: %i[username email]
|
80
|
+
# def data
|
81
|
+
# [{username: 'foo', email: 'bar', password: 'Example'}]
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# If you need to seed a different way, put your own custom +seed+ method in
|
86
|
+
# your seeder class and do whatever needs to be done.
|
6
87
|
class Seeder
|
7
88
|
##
|
8
89
|
# The allowed seeding methods.
|
@@ -12,11 +93,10 @@ module Planter
|
|
12
93
|
|
13
94
|
##
|
14
95
|
# Array of hashes used to create records. Your class must set this
|
15
|
-
# attribute when using +
|
96
|
+
# attribute when using +data_array+ seeding method, although it's probably
|
16
97
|
# more likely that you'll want to define a method that returns a new set of
|
17
|
-
# data each time (via +Faker+, +Array#sample+, etc.). When using
|
18
|
-
# +
|
19
|
-
# override this.
|
98
|
+
# data each time (via +Faker+, +Array#sample+, etc.). When using +csv+,
|
99
|
+
# +data+ will be set to the data within the csv. You can override this.
|
20
100
|
#
|
21
101
|
# @return [Array]
|
22
102
|
attr_reader :data
|
@@ -38,6 +118,8 @@ module Planter
|
|
38
118
|
#
|
39
119
|
# @kwarg [Symbol, String] csv_name
|
40
120
|
#
|
121
|
+
# @kwarg [Symbol, String] unique_columns
|
122
|
+
#
|
41
123
|
# @example
|
42
124
|
# require 'planter'
|
43
125
|
# class UsersSeeder < Planter::Seeder
|
@@ -46,7 +128,8 @@ module Planter
|
|
46
128
|
# model: 'User'
|
47
129
|
# parent_model: 'Person',
|
48
130
|
# association: :users,
|
49
|
-
# csv_name: :awesome_users
|
131
|
+
# csv_name: :awesome_users,
|
132
|
+
# unique_columns %i[username email]
|
50
133
|
# end
|
51
134
|
def self.seeding_method(
|
52
135
|
method,
|
@@ -54,7 +137,8 @@ module Planter
|
|
54
137
|
model: to_s.delete_suffix('Seeder').singularize,
|
55
138
|
parent_model: nil,
|
56
139
|
association: nil,
|
57
|
-
csv_name: nil
|
140
|
+
csv_name: nil,
|
141
|
+
unique_columns: nil
|
58
142
|
)
|
59
143
|
if !SEEDING_METHODS.include?(method.intern)
|
60
144
|
raise ArgumentError, "Method must be one of #{SEEDING_METHODS.join(', ')}"
|
@@ -68,6 +152,11 @@ module Planter
|
|
68
152
|
@parent_model = parent_model
|
69
153
|
@association = @parent_model && (association || determine_association)
|
70
154
|
@csv_file = determine_csv_filename(csv_name) if @seeding_method == :csv
|
155
|
+
@unique_columns =
|
156
|
+
case unique_columns
|
157
|
+
when String, Symbol then [unique_columns.intern]
|
158
|
+
when Array then unique_columns.map(&:intern)
|
159
|
+
end
|
71
160
|
end
|
72
161
|
|
73
162
|
def self.determine_association # :nodoc:
|
@@ -89,7 +178,7 @@ module Planter
|
|
89
178
|
).to_s + '.csv'
|
90
179
|
[file, "#{file}.erb"].each do |f|
|
91
180
|
fname = Rails.root.join(Planter.config.csv_files_directory, f).to_s
|
92
|
-
return fname if File.file?(fname)
|
181
|
+
return fname if ::File.file?(fname)
|
93
182
|
end
|
94
183
|
|
95
184
|
raise ArgumentError, "Couldn't find csv for #{@model}"
|
@@ -162,14 +251,23 @@ module Planter
|
|
162
251
|
@csv_file ||= self.class.instance_variable_get('@csv_file')
|
163
252
|
end
|
164
253
|
|
254
|
+
##
|
255
|
+
# When creating a record, the fields that will be used to look up the
|
256
|
+
# record. If it already exists, a new one will not be created.
|
257
|
+
#
|
258
|
+
# @return [Array]
|
259
|
+
def unique_columns
|
260
|
+
@unique_columns ||= self.class.instance_variable_get('@unique_columns')
|
261
|
+
end
|
262
|
+
|
165
263
|
##
|
166
264
|
# Creates records from the +data+ attribute.
|
167
265
|
def create_records
|
168
266
|
data.each do |rec|
|
169
267
|
number_of_records.times do
|
170
|
-
|
171
|
-
|
172
|
-
).first_or_create!
|
268
|
+
rec.transform_values { |value| value == 'NULL' ? nil : value }
|
269
|
+
unique, attrs = split_record(rec)
|
270
|
+
model.constantize.where(unique).first_or_create!(attrs)
|
173
271
|
end
|
174
272
|
end
|
175
273
|
end
|
@@ -187,34 +285,47 @@ module Planter
|
|
187
285
|
|
188
286
|
private
|
189
287
|
|
190
|
-
def create_method
|
288
|
+
def create_method # :nodoc:
|
191
289
|
parent_model.constantize.reflect_on_association(
|
192
290
|
association
|
193
291
|
).macro.to_s.include?('many') ? :create_has_many : :create_has_one
|
194
292
|
end
|
195
293
|
|
196
|
-
def create_has_many(assoc_rec, association, rec)
|
197
|
-
|
294
|
+
def create_has_many(assoc_rec, association, rec) # :nodoc:
|
295
|
+
unique, attrs = split_record(rec)
|
296
|
+
assoc_rec.public_send(association).where(unique).first_or_create!(attrs)
|
198
297
|
end
|
199
298
|
|
200
|
-
def create_has_one(assoc_rec, association, rec)
|
201
|
-
assoc_rec.public_send(
|
299
|
+
def create_has_one(assoc_rec, association, rec) # :nodoc:
|
300
|
+
if assoc_rec.public_send(association)
|
301
|
+
assoc_rec.public_send(association).update_attributes(rec)
|
302
|
+
else
|
303
|
+
assoc_rec.public_send("create_#{association}", rec)
|
304
|
+
end
|
202
305
|
end
|
203
306
|
|
204
307
|
def validate_attributes # :nodoc:
|
205
308
|
case seeding_method.intern
|
206
309
|
when :csv
|
207
|
-
contents = File.read(csv_file)
|
310
|
+
contents = ::File.read(csv_file)
|
208
311
|
if csv_file.end_with?('.erb')
|
209
312
|
contents = ERB.new(contents, trim_mode: '<>').result(binding)
|
210
313
|
end
|
211
314
|
|
212
|
-
@data ||= ::CSV.parse(
|
315
|
+
@data ||= ::CSV.parse(
|
316
|
+
contents, headers: true, header_converters: :symbol
|
317
|
+
).map(&:to_hash)
|
213
318
|
when :data_array
|
214
319
|
raise "Must define '@data'" if public_send(:data).nil?
|
215
320
|
else
|
216
321
|
raise("Must set 'seeding_method'")
|
217
322
|
end
|
218
323
|
end
|
324
|
+
|
325
|
+
def split_record(rec) # :nodoc:
|
326
|
+
return [rec, {}] unless unique_columns
|
327
|
+
u = unique_columns.each_with_object({}) { |c, h| h[c] = rec.delete(c) }
|
328
|
+
[u, rec]
|
329
|
+
end
|
219
330
|
end
|
220
331
|
end
|
data/lib/planter/version.rb
CHANGED
data/lib/planter.rb
CHANGED
@@ -8,68 +8,21 @@ require 'planter/config'
|
|
8
8
|
require 'planter/seeder'
|
9
9
|
|
10
10
|
##
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# seeder files are located can be changed via an initializer.
|
11
|
+
# The main module for the plugin. It nicely wraps the +Planter::Config+ class
|
12
|
+
# so that you can customize the plugin via an initializer or in the
|
13
|
+
# +db/seeds.rb+ file. This is how you'll specify your list of seeders to use,
|
14
|
+
# along with customizing the +seeders_directory+ and +csv_files_directory+.
|
16
15
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# table name with a +csv+ file extension. The directory where the seed files
|
22
|
-
# are kept can be changed via an initializer.
|
23
|
-
# # db/seeds/users_seeder.rb
|
24
|
-
# require 'planter'
|
25
|
-
# class UsersSeeder < Planter::Seeder
|
26
|
-
# seeding_method :csv, csv_name: '/home/me/users.csv'
|
16
|
+
# Planter.configure do |config|
|
17
|
+
# config.seeders = %i[users]
|
18
|
+
# config.seeders_directory = 'db/seeds'
|
19
|
+
# config.csv_files_directory = 'db/seed_files'
|
27
20
|
# end
|
28
21
|
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# hashes. Note that this class already provides the +attr_reader+ for this
|
32
|
-
# attribute, so the most you have to do it create instance variables in your
|
33
|
-
# constructor. If if you want your data to be different for each new record
|
34
|
-
# (via Faker, +Array#sample+, etc.), you'll probably want to supply a method
|
35
|
-
# called data that returns an array of new data each time.
|
36
|
-
# require 'planter'
|
37
|
-
# class UsersSeeder < Planter::Seeder
|
38
|
-
# seeding_method :data_array
|
39
|
-
# def data
|
40
|
-
# [{foo: 'bar', baz: 'bar'}]
|
41
|
-
# end
|
42
|
-
# end
|
43
|
-
#
|
44
|
-
# In both of the above methods, you can specify +parent_model+ and
|
45
|
-
# +association+. If specified, records will be created via that parent model's
|
46
|
-
# association. If +association+ is not provided, it will be assumed to be the
|
47
|
-
# model name, pluralized and snake-cased (implying a +has_many+ relationship).
|
48
|
-
# For example, if we're seeding the users table, and the model is +User+, the
|
49
|
-
# association will default to +users+.
|
50
|
-
# require 'planter'
|
51
|
-
# class UsersSeeder < Planter::Seeder
|
52
|
-
# seeding_method :data_array, parent_model: 'Person', association: :users
|
53
|
-
# def data
|
54
|
-
# [{foo: 'bar', baz: 'bar'}]
|
55
|
-
# end
|
56
|
-
# end
|
22
|
+
# To then seed your application, simply call the +seed+ method from your
|
23
|
+
# +db/seeds.rb+ file (or wherever you need to call it from).
|
57
24
|
#
|
58
|
-
#
|
59
|
-
# in the +data+ array will get created. The default is 1. Note that if this
|
60
|
-
# attribute is set alongside +parent_model+ and +association+,
|
61
|
-
# +number_of_records+ will be how many records will be created for each record
|
62
|
-
# in the parent table.
|
63
|
-
# require 'planter'
|
64
|
-
# class UsersSeeder < Planter::Seeder
|
65
|
-
# seeding_method :data_array, number_of_records: 5
|
66
|
-
# def data
|
67
|
-
# [{foo: 'bar', baz: 'bar'}]
|
68
|
-
# end
|
69
|
-
# end
|
70
|
-
#
|
71
|
-
# If you need to seed a different way, put your own custom +seed+ method in
|
72
|
-
# your seeder class and do whatever needs to be done.
|
25
|
+
# Planter.seed
|
73
26
|
module Planter
|
74
27
|
##
|
75
28
|
# The seeder configuration.
|
@@ -90,13 +43,14 @@ module Planter
|
|
90
43
|
##
|
91
44
|
# Quick way of configuring the directories via an initializer.
|
92
45
|
#
|
93
|
-
# @return [
|
46
|
+
# @return [Planter::Config]
|
94
47
|
#
|
95
48
|
# @example
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
49
|
+
# require 'planter'
|
50
|
+
# Planter.configure do |config|
|
51
|
+
# config.seeders = %i[users]
|
52
|
+
# config.seeders_directory = 'db/seeds'
|
53
|
+
# config.csv_files_directory = 'db/seed_files'
|
100
54
|
# end
|
101
55
|
def self.configure
|
102
56
|
config.tap { |c| yield c }
|
@@ -104,20 +58,21 @@ module Planter
|
|
104
58
|
|
105
59
|
##
|
106
60
|
# This is the method to call from your +db/seeds.rb+. It callse the seeders
|
107
|
-
# listed in +Planter.config.seeders+. To call specific seeders at
|
108
|
-
#
|
109
|
-
#
|
61
|
+
# listed in +Planter.config.seeders+. To call specific seeders at runtime,
|
62
|
+
# you can set the +SEEDERS+ environmental variable to a comma-separated list
|
63
|
+
# of seeders, like +rails db:seed SEEDERS=users,accounts+.
|
110
64
|
#
|
111
65
|
# @example
|
112
|
-
#
|
66
|
+
# # db/seeds.rb, assuming your +configure+ block is in an initializer.
|
67
|
+
# Planter.seed
|
113
68
|
def self.seed
|
114
69
|
seeders = ENV['SEEDERS']&.split(',') || config.seeders&.map(&:to_s)
|
115
|
-
raise RuntimeError, 'No seeders specified
|
70
|
+
raise RuntimeError, 'No seeders specified' unless seeders&.any?
|
116
71
|
|
117
|
-
seeders.each do |
|
118
|
-
require Rails.root.join(config.seeders_directory, "#{
|
119
|
-
puts "Seeding #{
|
120
|
-
"#{
|
72
|
+
seeders.each do |s|
|
73
|
+
require Rails.root.join(config.seeders_directory, "#{s}_seeder.rb").to_s
|
74
|
+
puts "Seeding #{s}" unless config.quiet
|
75
|
+
"#{s.camelize}Seeder".constantize.new.seed
|
121
76
|
end
|
122
77
|
end
|
123
78
|
end
|
@@ -1,4 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require 'planter'
|
2
|
+
|
3
|
+
namespace :planter do
|
4
|
+
desc 'Seed application. Use this to keep planter separate from db:seed'
|
5
|
+
task seed: :environment do
|
6
|
+
Planter.configure do |config|
|
7
|
+
# NOTE: the seed method already looks for ENV['SEEDERS']
|
8
|
+
ENV['SEEDERS_DIRECTORY'] && config.seeders_directory = ENV['SEEDERS_DIRECTORY']
|
9
|
+
ENV['CSV_FILES_DIRECTORY'] && config.csv_files_directory = ENV['CSV_FILES_DIRECTORY']
|
10
|
+
end
|
11
|
+
Planter.seed
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: planter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Gray
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -41,6 +41,8 @@ files:
|
|
41
41
|
- LICENSE
|
42
42
|
- README.md
|
43
43
|
- Rakefile
|
44
|
+
- lib/generators/planter/initializer_generator.rb
|
45
|
+
- lib/generators/planter/seeder_generator.rb
|
44
46
|
- lib/planter.rb
|
45
47
|
- lib/planter/config.rb
|
46
48
|
- lib/planter/railtie.rb
|
@@ -70,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
72
|
- !ruby/object:Gem::Version
|
71
73
|
version: '0'
|
72
74
|
requirements: []
|
73
|
-
rubygems_version: 3.2.
|
75
|
+
rubygems_version: 3.2.22
|
74
76
|
signing_key:
|
75
77
|
specification_version: 4
|
76
78
|
summary: Framework for seeding rails applications.
|