planter 0.0.8 → 0.0.12
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 +38 -13
- data/lib/generators/planter/initializer_generator.rb +6 -2
- data/lib/planter/config.rb +9 -0
- data/lib/planter/seeder.rb +77 -16
- data/lib/planter/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37c19399e25198fe0545690d5b5568c5bd91b4736258af3d8664c36abe882889
|
4
|
+
data.tar.gz: a399b54a606d7c0e98d49f0bad5abff1fc4726d96eab3573c82d1dc649b83b1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6275a47f463227b86374e327781edd92bbd9cdf9399bafa68c6c4cb3316ae812cf081509a26e81e04101f9cd4af43396f2c008477741f00f475ea09436353ba8
|
7
|
+
data.tar.gz: 1a5a27d9253b78ae0c1c0526c1f8dcb977a428ec5c62cb4239f5542413e1f5020c68d8ee0d356ded4c1f3094c7f449f03fefb72180250388de81f8c44c2c6a63
|
data/README.md
CHANGED
@@ -19,10 +19,12 @@ Features include:
|
|
19
19
|
You can view the documentation [here](https://evanthegrayt.github.io/planter/).
|
20
20
|
|
21
21
|
## Installation
|
22
|
-
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.
|
23
25
|
|
24
26
|
```ruby
|
25
|
-
gem 'planter'
|
27
|
+
gem 'planter', '0.0.10'
|
26
28
|
```
|
27
29
|
|
28
30
|
And then execute:
|
@@ -50,8 +52,8 @@ Planter.configure do |config|
|
|
50
52
|
##
|
51
53
|
# The list of seeders. These files are stored in the
|
52
54
|
# config.seeders_directory, which can be changed below. When a new
|
53
|
-
#
|
54
|
-
# list. If the order is incorrect, you'll need to adjust
|
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.
|
55
57
|
# Just be sure to keep the ending bracket on its own line, or the
|
56
58
|
# generator won't know where to put new elements.
|
57
59
|
config.seeders = %i[
|
@@ -64,6 +66,10 @@ Planter.configure do |config|
|
|
64
66
|
##
|
65
67
|
# The directory where CSVs are kept.
|
66
68
|
# config.csv_files_directory = 'db/seed_files'
|
69
|
+
|
70
|
+
##
|
71
|
+
# The default trim mode for ERB.
|
72
|
+
# config.erb_trim_mode = nil
|
67
73
|
end
|
68
74
|
```
|
69
75
|
|
@@ -133,18 +139,37 @@ class UsersSeeder < Planter::Seeder
|
|
133
139
|
end
|
134
140
|
```
|
135
141
|
|
136
|
-
`ERB` can be used in the CSV files if you name
|
137
|
-
|
138
|
-
|
139
|
-
|
142
|
+
`ERB` can be used in the CSV files if you end the file name with `.csv.erb`.
|
143
|
+
For example, `users.csv.erb`.
|
144
|
+
|
145
|
+
```
|
146
|
+
participant_id,name
|
147
|
+
<%= Participant.find_by(email: 'test1@example.com').id %>,"Test User1"
|
148
|
+
<%= Participant.find_by(email: 'test2@example.com').id %>,"Test User2"
|
149
|
+
```
|
150
|
+
|
151
|
+
Note that, if you need to change the trim mode for ERB, you can set a default in
|
152
|
+
the initializer.
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
Planter.configure do |config|
|
156
|
+
config.seeders = %i[
|
157
|
+
users
|
158
|
+
]
|
159
|
+
config.erb_trim_mode = '<>'
|
160
|
+
end
|
161
|
+
```
|
162
|
+
|
163
|
+
...or, for individual seeders, via `seeding_method`.
|
140
164
|
|
141
|
-
```
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
test2@example.com,<%= count += 1 %>
|
165
|
+
```ruby
|
166
|
+
class UsersSeeder < Planter::Seeder
|
167
|
+
seeding_method :csv, erb_trim_mode: '<>'
|
168
|
+
end
|
146
169
|
```
|
147
170
|
|
171
|
+
For help with `erb_trim_mode`, see the help documentation for `ERB::new`.
|
172
|
+
|
148
173
|
Running `rails planter:seed` will now seed your `users` table.
|
149
174
|
|
150
175
|
## Seeding from a data array
|
@@ -11,8 +11,8 @@ module Planter
|
|
11
11
|
##
|
12
12
|
# The list of seeders. These files are stored in the
|
13
13
|
# config.seeders_directory, which can be changed below. When a new
|
14
|
-
#
|
15
|
-
# list. If the order is incorrect, you'll need to adjust
|
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
16
|
# Just be sure to keep the ending bracket on its own line, or the
|
17
17
|
# generator won't know where to put new elements.
|
18
18
|
config.seeders = %i[
|
@@ -25,6 +25,10 @@ module Planter
|
|
25
25
|
##
|
26
26
|
# The directory where CSVs are kept.
|
27
27
|
# config.csv_files_directory = 'db/seed_files'
|
28
|
+
|
29
|
+
##
|
30
|
+
# The default trim mode for ERB.
|
31
|
+
# config.erb_trim_mode = nil
|
28
32
|
end
|
29
33
|
EOF
|
30
34
|
end
|
data/lib/planter/config.rb
CHANGED
@@ -42,6 +42,15 @@ module Planter
|
|
42
42
|
# @return [Boolean]
|
43
43
|
attr_accessor :quiet
|
44
44
|
|
45
|
+
##
|
46
|
+
# The default trim mode for ERB. Must be "%", "<>", ">", or "-".
|
47
|
+
# For more information, see documentation for +ERB::new+.
|
48
|
+
#
|
49
|
+
# @param [String] erb_trim_mode
|
50
|
+
#
|
51
|
+
# @return [String]
|
52
|
+
attr_accessor :erb_trim_mode
|
53
|
+
|
45
54
|
##
|
46
55
|
# Create a new instance of the config.
|
47
56
|
def initialize
|
data/lib/planter/seeder.rb
CHANGED
@@ -65,6 +65,23 @@ module Planter
|
|
65
65
|
# end
|
66
66
|
# end
|
67
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
|
+
#
|
68
85
|
# If you need to seed a different way, put your own custom +seed+ method in
|
69
86
|
# your seeder class and do whatever needs to be done.
|
70
87
|
class Seeder
|
@@ -101,6 +118,10 @@ module Planter
|
|
101
118
|
#
|
102
119
|
# @kwarg [Symbol, String] csv_name
|
103
120
|
#
|
121
|
+
# @kwarg [Symbol, String] unique_columns
|
122
|
+
#
|
123
|
+
# @kwarg [String] erb_trim_mode
|
124
|
+
#
|
104
125
|
# @example
|
105
126
|
# require 'planter'
|
106
127
|
# class UsersSeeder < Planter::Seeder
|
@@ -109,15 +130,19 @@ module Planter
|
|
109
130
|
# model: 'User'
|
110
131
|
# parent_model: 'Person',
|
111
132
|
# association: :users,
|
112
|
-
# csv_name: :awesome_users
|
133
|
+
# csv_name: :awesome_users,
|
134
|
+
# unique_columns %i[username email],
|
135
|
+
# erb_trim_mode: '<>'
|
113
136
|
# end
|
114
137
|
def self.seeding_method(
|
115
138
|
method,
|
116
139
|
number_of_records: 1,
|
117
|
-
model:
|
140
|
+
model: nil,
|
118
141
|
parent_model: nil,
|
119
142
|
association: nil,
|
120
|
-
csv_name: nil
|
143
|
+
csv_name: nil,
|
144
|
+
unique_columns: nil,
|
145
|
+
erb_trim_mode: nil
|
121
146
|
)
|
122
147
|
if !SEEDING_METHODS.include?(method.intern)
|
123
148
|
raise ArgumentError, "Method must be one of #{SEEDING_METHODS.join(', ')}"
|
@@ -127,10 +152,16 @@ module Planter
|
|
127
152
|
|
128
153
|
@seeding_method = method
|
129
154
|
@number_of_records = number_of_records
|
130
|
-
@model = model
|
155
|
+
@model = model || to_s.delete_suffix('Seeder').singularize
|
131
156
|
@parent_model = parent_model
|
132
157
|
@association = @parent_model && (association || determine_association)
|
133
158
|
@csv_file = determine_csv_filename(csv_name) if @seeding_method == :csv
|
159
|
+
@erb_trim_mode = erb_trim_mode || Planter.config.erb_trim_mode
|
160
|
+
@unique_columns =
|
161
|
+
case unique_columns
|
162
|
+
when String, Symbol then [unique_columns.intern]
|
163
|
+
when Array then unique_columns.map(&:intern)
|
164
|
+
end
|
134
165
|
end
|
135
166
|
|
136
167
|
def self.determine_association # :nodoc:
|
@@ -152,7 +183,7 @@ module Planter
|
|
152
183
|
).to_s + '.csv'
|
153
184
|
[file, "#{file}.erb"].each do |f|
|
154
185
|
fname = Rails.root.join(Planter.config.csv_files_directory, f).to_s
|
155
|
-
return fname if File.file?(fname)
|
186
|
+
return fname if ::File.file?(fname)
|
156
187
|
end
|
157
188
|
|
158
189
|
raise ArgumentError, "Couldn't find csv for #{@model}"
|
@@ -225,14 +256,31 @@ module Planter
|
|
225
256
|
@csv_file ||= self.class.instance_variable_get('@csv_file')
|
226
257
|
end
|
227
258
|
|
259
|
+
##
|
260
|
+
# When creating a record, the fields that will be used to look up the
|
261
|
+
# record. If it already exists, a new one will not be created.
|
262
|
+
#
|
263
|
+
# @return [Array]
|
264
|
+
def unique_columns
|
265
|
+
@unique_columns ||= self.class.instance_variable_get('@unique_columns')
|
266
|
+
end
|
267
|
+
|
268
|
+
##
|
269
|
+
# What trim mode should ERB use?
|
270
|
+
#
|
271
|
+
# @return [String]
|
272
|
+
def erb_trim_mode
|
273
|
+
@erb_trim_mode ||= self.class.instance_variable_get('@erb_trim_mode')
|
274
|
+
end
|
275
|
+
|
228
276
|
##
|
229
277
|
# Creates records from the +data+ attribute.
|
230
278
|
def create_records
|
231
279
|
data.each do |rec|
|
232
280
|
number_of_records.times do
|
233
|
-
|
234
|
-
|
235
|
-
).first_or_create!
|
281
|
+
rec.transform_values { |value| value == 'NULL' ? nil : value }
|
282
|
+
unique, attrs = split_record(rec)
|
283
|
+
model.constantize.where(unique).first_or_create!(attrs)
|
236
284
|
end
|
237
285
|
end
|
238
286
|
end
|
@@ -250,34 +298,47 @@ module Planter
|
|
250
298
|
|
251
299
|
private
|
252
300
|
|
253
|
-
def create_method
|
301
|
+
def create_method # :nodoc:
|
254
302
|
parent_model.constantize.reflect_on_association(
|
255
303
|
association
|
256
304
|
).macro.to_s.include?('many') ? :create_has_many : :create_has_one
|
257
305
|
end
|
258
306
|
|
259
|
-
def create_has_many(assoc_rec, association, rec)
|
260
|
-
|
307
|
+
def create_has_many(assoc_rec, association, rec) # :nodoc:
|
308
|
+
unique, attrs = split_record(rec)
|
309
|
+
assoc_rec.public_send(association).where(unique).first_or_create!(attrs)
|
261
310
|
end
|
262
311
|
|
263
|
-
def create_has_one(assoc_rec, association, rec)
|
264
|
-
assoc_rec.public_send(
|
312
|
+
def create_has_one(assoc_rec, association, rec) # :nodoc:
|
313
|
+
if assoc_rec.public_send(association)
|
314
|
+
assoc_rec.public_send(association).update_attributes(rec)
|
315
|
+
else
|
316
|
+
assoc_rec.public_send("create_#{association}", rec)
|
317
|
+
end
|
265
318
|
end
|
266
319
|
|
267
320
|
def validate_attributes # :nodoc:
|
268
321
|
case seeding_method.intern
|
269
322
|
when :csv
|
270
|
-
contents = File.read(csv_file)
|
323
|
+
contents = ::File.read(csv_file)
|
271
324
|
if csv_file.end_with?('.erb')
|
272
|
-
contents = ERB.new(contents, trim_mode:
|
325
|
+
contents = ERB.new(contents, trim_mode: erb_trim_mode).result(binding)
|
273
326
|
end
|
274
327
|
|
275
|
-
@data ||= ::CSV.parse(
|
328
|
+
@data ||= ::CSV.parse(
|
329
|
+
contents, headers: true, header_converters: :symbol
|
330
|
+
).map(&:to_hash)
|
276
331
|
when :data_array
|
277
332
|
raise "Must define '@data'" if public_send(:data).nil?
|
278
333
|
else
|
279
334
|
raise("Must set 'seeding_method'")
|
280
335
|
end
|
281
336
|
end
|
337
|
+
|
338
|
+
def split_record(rec) # :nodoc:
|
339
|
+
return [rec, {}] unless unique_columns
|
340
|
+
u = unique_columns.each_with_object({}) { |c, h| h[c] = rec.delete(c) }
|
341
|
+
[u, rec]
|
342
|
+
end
|
282
343
|
end
|
283
344
|
end
|
data/lib/planter/version.rb
CHANGED
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.12
|
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-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -72,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: '0'
|
74
74
|
requirements: []
|
75
|
-
rubygems_version: 3.2.
|
75
|
+
rubygems_version: 3.2.22
|
76
76
|
signing_key:
|
77
77
|
specification_version: 4
|
78
78
|
summary: Framework for seeding rails applications.
|