planter 0.0.8 → 0.0.9

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: cefea9dd4547f81df2480f10a92ed64738475a21db8237dac4599a060a80cf19
4
- data.tar.gz: 660ecdca12dc88752d353a39e0a6fc0bef2582b7203628002e23f6d246d49589
3
+ metadata.gz: 61c2952a2b44b89c48245554cd6be4b19598891aa958b3f2f0dd3e3d2548a079
4
+ data.tar.gz: 91e099c652ce4bfb0bf87320f9efa3d1e0e0826ae031e17e967563beb8561f19
5
5
  SHA512:
6
- metadata.gz: 486bf0a34ac192c6c1295a1b628d25b5e685a83d92700f99291ef35e2ea58b30f5db976057ae87e03a76d48ee29bceacfcde5e5d1018488976f2304f079aafd1
7
- data.tar.gz: 3ab0665aa4c97a0a7f405bc93604256a90c2c7e88745d5ded6f908fc17f914fb76cc883f69c5a709fd5210902bc5039f80a294cc26548a8eead99695a1dda529
6
+ metadata.gz: d70a187f4064ab1081a5a4b3df180f4ced5436601151029fca74b985cc0658e0422b56f338693b08a885a5dfc7d241357ef86144373825d8553117c3e7f6f30e
7
+ data.tar.gz: 923979e971e3cbc573a9eaffbc39481d8fc8a4930894de1ea8d8f4ef79c3f6d7bbaba0ab111d0099ee67298b336373a0836802126c5d5bba4c237eb41ab0c5d8
data/README.md CHANGED
@@ -50,7 +50,7 @@ Planter.configure do |config|
50
50
  ##
51
51
  # The list of seeders. These files are stored in the
52
52
  # config.seeders_directory, which can be changed below. When a new
53
- # seeeder is generated, it will be appended to the bottom of this
53
+ # seeder is generated, it will be appended to the bottom of this
54
54
  # list. If the order is incorrect, you'll need to adjust the it.
55
55
  # Just be sure to keep the ending bracket on its own line, or the
56
56
  # generator won't know where to put new elements.
@@ -11,7 +11,7 @@ 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
- # seeeder is generated, it will be appended to the bottom of this
14
+ # seeder is generated, it will be appended to the bottom of this
15
15
  # list. If the order is incorrect, you'll need to adjust the 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.
@@ -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,8 @@ module Planter
101
118
  #
102
119
  # @kwarg [Symbol, String] csv_name
103
120
  #
121
+ # @kwarg [Symbol, String] unique_columns
122
+ #
104
123
  # @example
105
124
  # require 'planter'
106
125
  # class UsersSeeder < Planter::Seeder
@@ -109,7 +128,8 @@ module Planter
109
128
  # model: 'User'
110
129
  # parent_model: 'Person',
111
130
  # association: :users,
112
- # csv_name: :awesome_users
131
+ # csv_name: :awesome_users,
132
+ # unique_columns %i[username email]
113
133
  # end
114
134
  def self.seeding_method(
115
135
  method,
@@ -117,7 +137,8 @@ module Planter
117
137
  model: to_s.delete_suffix('Seeder').singularize,
118
138
  parent_model: nil,
119
139
  association: nil,
120
- csv_name: nil
140
+ csv_name: nil,
141
+ unique_columns: nil
121
142
  )
122
143
  if !SEEDING_METHODS.include?(method.intern)
123
144
  raise ArgumentError, "Method must be one of #{SEEDING_METHODS.join(', ')}"
@@ -131,6 +152,11 @@ module Planter
131
152
  @parent_model = parent_model
132
153
  @association = @parent_model && (association || determine_association)
133
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
134
160
  end
135
161
 
136
162
  def self.determine_association # :nodoc:
@@ -152,7 +178,7 @@ module Planter
152
178
  ).to_s + '.csv'
153
179
  [file, "#{file}.erb"].each do |f|
154
180
  fname = Rails.root.join(Planter.config.csv_files_directory, f).to_s
155
- return fname if File.file?(fname)
181
+ return fname if ::File.file?(fname)
156
182
  end
157
183
 
158
184
  raise ArgumentError, "Couldn't find csv for #{@model}"
@@ -225,14 +251,23 @@ module Planter
225
251
  @csv_file ||= self.class.instance_variable_get('@csv_file')
226
252
  end
227
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
+
228
263
  ##
229
264
  # Creates records from the +data+ attribute.
230
265
  def create_records
231
266
  data.each do |rec|
232
267
  number_of_records.times do
233
- model.constantize.where(
234
- rec.transform_values { |value| value == 'NULL' ? nil : value }
235
- ).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)
236
271
  end
237
272
  end
238
273
  end
@@ -250,34 +285,47 @@ module Planter
250
285
 
251
286
  private
252
287
 
253
- def create_method
288
+ def create_method # :nodoc:
254
289
  parent_model.constantize.reflect_on_association(
255
290
  association
256
291
  ).macro.to_s.include?('many') ? :create_has_many : :create_has_one
257
292
  end
258
293
 
259
- def create_has_many(assoc_rec, association, rec)
260
- assoc_rec.public_send(association).where(rec).first_or_create!
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)
261
297
  end
262
298
 
263
- def create_has_one(assoc_rec, association, rec)
264
- assoc_rec.public_send("create_#{association}", rec)
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
265
305
  end
266
306
 
267
307
  def validate_attributes # :nodoc:
268
308
  case seeding_method.intern
269
309
  when :csv
270
- contents = File.read(csv_file)
310
+ contents = ::File.read(csv_file)
271
311
  if csv_file.end_with?('.erb')
272
312
  contents = ERB.new(contents, trim_mode: '<>').result(binding)
273
313
  end
274
314
 
275
- @data ||= ::CSV.parse(contents, headers: true).map(&:to_hash)
315
+ @data ||= ::CSV.parse(
316
+ contents, headers: true, header_converters: :symbol
317
+ ).map(&:to_hash)
276
318
  when :data_array
277
319
  raise "Must define '@data'" if public_send(:data).nil?
278
320
  else
279
321
  raise("Must set 'seeding_method'")
280
322
  end
281
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
282
330
  end
283
331
  end
@@ -21,7 +21,7 @@ module Planter
21
21
  # Patch version.
22
22
  #
23
23
  # @return [Integer]
24
- PATCH = 8
24
+ PATCH = 9
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.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Gray
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-26 00:00:00.000000000 Z
11
+ date: 2021-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -57,7 +57,7 @@ metadata:
57
57
  homepage_uri: https://github.com/evanthegrayt/planter
58
58
  source_code_uri: https://github.com/evanthegrayt/planter
59
59
  documentation_uri: https://evanthegrayt.github.io/planter/
60
- post_install_message:
60
+ post_install_message:
61
61
  rdoc_options: []
62
62
  require_paths:
63
63
  - lib
@@ -72,8 +72,8 @@ 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.3
76
- signing_key:
75
+ rubygems_version: 3.2.15
76
+ signing_key:
77
77
  specification_version: 4
78
78
  summary: Framework for seeding rails applications.
79
79
  test_files: []