planter 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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: []