planter 0.0.15 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76a26d2138c0fff92d6c99503e2f5b5c88aa5333d3151b4c4c27ed4b29667f7b
4
- data.tar.gz: 322850357a4886588218e7a7800b5a0f23310506f650c284acb963d0a3a994ae
3
+ metadata.gz: b346415e35c538e46222ced2131792a27f778fafe169143116c6908ddca88aac
4
+ data.tar.gz: ed3952a7fd92566b2acb31e0fee881549675f40aa579ebe9115db2f86f302eb0
5
5
  SHA512:
6
- metadata.gz: 9e7fb3cdefd3dd6ca635c11a9f5725dbc83299d2e3b5df59dbdd9f3eff0dfc718f2d6ab00fcd6b8de56c7a37abaca8c5af73b697e31ef406ae7cf3f75380191e
7
- data.tar.gz: 51ffeee246719300c2474aa86fa36b306f8996515da57dc308c4a8aa78f14bbed59b80596575d1f82534a809447b283ceed2c28e11daf92851ecfefd5b61a2cd
6
+ metadata.gz: d07501dd0544476e04b768277d870f035626f6c00218a9f248e6fe6f7dcae833757162b688a269066bc8daa5dae1d2fb6f20db7c45273245da60f900cde80f3f
7
+ data.tar.gz: '09e7ba1054d15f7aa68aedaac7915fdda444eac1bff9630402e5f5999f872283e978b5e60b9581310cdd2bbc9ea4688d73b3fd7d6c8781b802b8bb21cee7fb8c'
data/README.md CHANGED
@@ -207,13 +207,16 @@ Running `rails planter:seed` should now seed your `users` table.
207
207
 
208
208
  You can also seed children records for every existing record of a parent model.
209
209
  For example, to seed an address for every user, you'd need to create an
210
- `AddressesSeeder` that uses the `parent_model` option, as seen below.
210
+ `AddressesSeeder` that uses the `parent` option, as seen below. This option
211
+ should be the name of the `belongs_to` association in your model. The primary
212
+ key, foreign key, and model name of the parent will all be determined by
213
+ reflecting on the association.
211
214
 
212
215
  ```ruby
213
216
  require 'faker'
214
217
 
215
218
  class AddressesSeeder < Planter::Seeder
216
- seeding_method :data_array, parent_model: 'User'
219
+ seeding_method :data_array, parent: :user
217
220
 
218
221
  def data
219
222
  [{
@@ -227,9 +230,7 @@ end
227
230
  ```
228
231
 
229
232
  Note that specifying `number_of_records` in this instance will create that many
230
- records *for each record of the parent model*. You can also specify the
231
- association if it's different from the table name, using the `:assocation`
232
- option.
233
+ records *for each record of the parent model*.
233
234
 
234
235
  ### Custom seeds
235
236
  To write your own custom seeds, just overload the `seed` method and do whatever
@@ -26,7 +26,7 @@ module Planter
26
26
  # Another way to seed is to create records from a data array. To do this,
27
27
  # your class must implement a +data+ attribute or method, which is an array
28
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
29
+ # attribute, so the most you have to do is create instance variables in your
30
30
  # constructor. If if you want your data to be different for each new record
31
31
  # (via Faker, +Array#sample+, etc.), you'll probably want to supply a method
32
32
  # called data that returns an array of new data each time.
@@ -38,15 +38,17 @@ module Planter
38
38
  # end
39
39
  # end
40
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+.
41
+ # In both of the above methods, you can specify a +parent+ association, which
42
+ # is the +belongs_to+ association name in your model, which, when specified,
43
+ # records will be created for each record in the parent table. For example,
44
+ # if we're seeding the users table, and the model is +User+, which belongs to
45
+ # +Person+, then doing the following will create a user record for each
46
+ # record in the Person table. Note that nothing is automatically done to
47
+ # prevent any validation errors; you must do this on your own, mostly likely
48
+ # using +Faker+ or a similar library.
47
49
  # require 'planter'
48
50
  # class UsersSeeder < Planter::Seeder
49
- # seeding_method :data_array, parent_model: 'Person', association: :users
51
+ # seeding_method :data_array, parent: :person
50
52
  # def data
51
53
  # [{foo: 'bar', baz: 'bar'}]
52
54
  # end
@@ -54,9 +56,8 @@ module Planter
54
56
  #
55
57
  # You can also set +number_of_records+ to determine how many times each
56
58
  # 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.
59
+ # this attribute is set alongside +parent+, +number_of_records+ will be how
60
+ # many records will be created for each record in the parent table.
60
61
  # require 'planter'
61
62
  # class UsersSeeder < Planter::Seeder
62
63
  # seeding_method :data_array, number_of_records: 5
@@ -127,7 +128,7 @@ module Planter
127
128
  # class must set this attribute via +seeding_method+.
128
129
  #
129
130
  # @return [String]
130
- class_attribute :parent_model
131
+ class_attribute :parent
131
132
 
132
133
  ##
133
134
  # The number of records to create from each record in the +data+ array. If
@@ -137,13 +138,6 @@ module Planter
137
138
  # @return [Integer]
138
139
  class_attribute :number_of_records
139
140
 
140
- ##
141
- # When using +parent_model+, the association name. Your class can set this
142
- # attribute via +seeding_method+.
143
- #
144
- # @return [Symbol]
145
- class_attribute :association
146
-
147
141
  ##
148
142
  # The csv file corresponding to the model.
149
143
  #
@@ -164,15 +158,15 @@ module Planter
164
158
  # it which +seeding_method+ to use. The argument to this method must be
165
159
  # included in the +SEEDING_METHODS+ array.
166
160
  #
167
- # @param [Symbol] seeding_method
161
+ # @param [Symbol] seed_method
168
162
  #
169
163
  # @kwarg [Integer] number_of_records
170
164
  #
171
165
  # @kwarg [String] model
172
166
  #
173
- # @kwarg [String] parent_model
167
+ # @kwarg [String] parent
174
168
  #
175
- # @kwarg [Symbol, String] association
169
+ # @kwarg [Symbol, String] parent
176
170
  #
177
171
  # @kwarg [Symbol, String] csv_name
178
172
  #
@@ -186,34 +180,29 @@ module Planter
186
180
  # seeding_method :csv,
187
181
  # number_of_records: 2,
188
182
  # model: 'User'
189
- # parent_model: 'Person',
190
- # association: :users,
183
+ # parent: :person,
191
184
  # csv_name: :awesome_users,
192
185
  # unique_columns %i[username email],
193
186
  # erb_trim_mode: '<>'
194
187
  # end
195
188
  def seeding_method(
196
- method,
189
+ seed_method,
197
190
  number_of_records: 1,
198
191
  model: nil,
199
- parent_model: nil,
200
- association: nil,
192
+ parent: nil,
201
193
  csv_name: nil,
202
194
  unique_columns: nil,
203
195
  erb_trim_mode: nil
204
196
  )
205
- if !SEEDING_METHODS.include?(method.intern)
197
+ if !SEEDING_METHODS.include?(seed_method.intern)
206
198
  raise ArgumentError, "Method must be: #{SEEDING_METHODS.join(', ')}"
207
- elsif association && !parent_model
208
- raise ArgumentError, "Must specify :parent_model with :association"
209
199
  end
210
200
 
211
- self.seed_method = method
201
+ self.seed_method = seed_method
212
202
  self.number_of_records = number_of_records
213
203
  self.model = model || to_s.delete_suffix('Seeder').singularize
214
- self.parent_model = parent_model
215
- self.association = parent_model && (association || determine_association)
216
- self.csv_file = determine_csv_filename(csv_name) if self.seed_method == :csv
204
+ self.parent = parent
205
+ self.csv_file = determine_csv_filename(csv_name) if seed_method == :csv
217
206
  self.erb_trim_mode = erb_trim_mode || Planter.config.erb_trim_mode
218
207
  self.unique_columns =
219
208
  case unique_columns
@@ -224,18 +213,6 @@ module Planter
224
213
 
225
214
  private
226
215
 
227
- def determine_association # :nodoc:
228
- associations =
229
- parent_model.constantize.reflect_on_all_associations.map(&:name)
230
- table = to_s.delete_suffix('Seeder').underscore.split('/').last
231
-
232
- [table, table.singularize].map(&:intern).each do |t|
233
- return t if associations.include?(t)
234
- end
235
-
236
- raise ArgumentError, "Couldn't determine association name"
237
- end
238
-
239
216
  def determine_csv_filename(csv_name) # :nodoc:
240
217
  file = (
241
218
  csv_name || "#{to_s.delete_suffix('Seeder').underscore}"
@@ -255,7 +232,7 @@ module Planter
255
232
  def seed
256
233
  validate_attributes
257
234
 
258
- parent_model ? create_records_from_parent : create_records
235
+ parent ? create_records_from_parent : create_records
259
236
  end
260
237
 
261
238
  protected
@@ -263,44 +240,23 @@ module Planter
263
240
  ##
264
241
  # Creates records from the +data+ attribute.
265
242
  def create_records
266
- data.each do |rec|
267
- number_of_records.times do
268
- rec.transform_values { |value| value == 'NULL' ? nil : value }
269
- unique, attrs = split_record(rec)
270
- model.constantize.where(unique).first_or_create!(attrs)
271
- end
272
- end
243
+ data.each { |record| create_record(record) }
273
244
  end
274
245
 
275
246
  ##
276
- # Create records from the +data+ attribute for each record in the
277
- # +parent_table+, via the specified +association+.
247
+ # Create records from the +data+ attribute for each record in the +parent+.
278
248
  def create_records_from_parent
279
- parent_model.constantize.all.each do |assoc_rec|
280
- number_of_records.times do
281
- data.each { |rec| send(create_method, assoc_rec, association, rec) }
282
- end
249
+ parent_model.constantize.pluck(primary_key).each do |parent_id|
250
+ data.each { |record| create_record(record, parent_id: parent_id) }
283
251
  end
284
252
  end
285
253
 
286
- private
287
-
288
- def create_method # :nodoc:
289
- parent_model.constantize.reflect_on_association(
290
- association
291
- ).macro.to_s.include?('many') ? :create_has_many : :create_has_one
292
- end
293
-
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)
297
- end
298
-
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)
254
+ def create_record(record, parent_id: nil)
255
+ number_of_records.times do
256
+ unique, attrs = split_record(record)
257
+ model.constantize.where(
258
+ unique.tap { |u| u[foreign_key] = parent_id if parent_id }
259
+ ).first_or_create!(attrs)
304
260
  end
305
261
  end
306
262
 
@@ -324,8 +280,29 @@ module Planter
324
280
 
325
281
  def split_record(rec) # :nodoc:
326
282
  return [rec, {}] unless unique_columns
283
+
327
284
  u = unique_columns.each_with_object({}) { |c, h| h[c] = rec.delete(c) }
328
285
  [u, rec]
329
286
  end
287
+
288
+ def association_options
289
+ @association_options ||=
290
+ model.constantize.reflect_on_association(parent).options
291
+ end
292
+
293
+ def primary_key
294
+ @primary_key ||=
295
+ association_options.fetch(:primary_key, :id)
296
+ end
297
+
298
+ def foreign_key
299
+ @foreign_key ||=
300
+ association_options.fetch(:foreign_key, "#{parent}_id")
301
+ end
302
+
303
+ def parent_model
304
+ @parent_model ||=
305
+ association_options.fetch(:class_name, parent.to_s.classify)
306
+ end
330
307
  end
331
308
  end
@@ -15,13 +15,13 @@ module Planter
15
15
  # Minor version.
16
16
  #
17
17
  # @return [Integer]
18
- MINOR = 0
18
+ MINOR = 1
19
19
 
20
20
  ##
21
21
  # Patch version.
22
22
  #
23
23
  # @return [Integer]
24
- PATCH = 15
24
+ PATCH = 1
25
25
 
26
26
  ##
27
27
  # Version as +[MAJOR, MINOR, PATCH]+
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.15
4
+ version: 0.1.1
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-12-27 00:00:00.000000000 Z
11
+ date: 2021-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails