Class: Planter::Seeder
- Inherits:
-
Object
- Object
- Planter::Seeder
- Defined in:
- lib/planter/seeder.rb
Overview
Class that seeders should inherit from. Seeders should be in db/seeds,
and named TABLE_seeder.rb, where TABLE is the name of the table being
seeded (for example, users_seeder.rb). If your seeder is named differently
than the table, you'll need to specify the table with the table option. The
seeder's class name should be the same as the file name, but camelized. So,
UsersSeeder. The directory where the seeder files are located can be
changed via an initializer.
To generate a seeder with a specific style, pass --seeding-method=csv,
--seeding-method=data-array, or --seeding-method=custom to
rails generate planter:seeder. When the csv method is used, the generator
also creates a CSV file with headers pulled from the table.
The most basic way to seed is to have a CSV file with the same name as the
table in db/seed_files/. So, users.csv. This CSV should have the
table's column names as headers. To seed using this method, your class
should look like the following. Note that :csv_name and :table are only
required if your seeder or CSV are named differently than the table being
seeded. The directory where the seed files are kept can be changed via an
initializer.
db/seeds/users_seeder.rb
require 'planter' class UsersSeeder < Planter::Seeder seeding_method :csv, csv_name: :users, table: :users end
Another way to seed is to create records from a data array. To do this,
your class must implement a data attribute or method, which is an array
of hashes. Note that this class already provides the attr_reader for this
attribute, so the most you have to do is create instance variables in your
constructor. If you want your data to be different for each new record
(via Faker, Array#sample, etc.), you'll probably want to supply a method
called data that returns an array of new data each time.
require 'planter'
class UsersSeeder < Planter::Seeder
seeding_method :data_array
def data
['bar', baz: 'bar']
end
end
In both of the above methods, you can specify a parent association, which
is interpreted by the configured adapter. With the default Active Record
adapter, parent is the belongs_to association name on a model-backed
table. When specified, records will be created for each record in the parent
table. Note that nothing is automatically done to prevent any validation
errors; you must do this on your own, most likely using Faker or a similar
library.
require 'planter'
class UsersSeeder < Planter::Seeder
seeding_method :data_array, parent: :person
def data
['bar', baz: 'bar']
end
end
You can also set number_of_records to determine how many times each
record in the data array will be created. The default is 1. Note that if
this attribute is set alongside parent, number_of_records will be how
many records will be created for each record in the parent table.
require 'planter'
class UsersSeeder < Planter::Seeder
seeding_method :data_array, number_of_records: 5
def data
['bar', baz: 'bar']
end
end
By default, all fields are used to look up the record. If it already
exists, it is not re-created. If you have specific fields that a record
should be looked up by, you can pass the unique_columns option. This will
attempt to look up the record by those fields only, and if one doesn't
exist, one will be created with the rest of the attributes. An example of
when this would be useful is with Devise; you can't pass password in the
create method, so specifying unique_columns on everything except
password allows it to be passed as an attribute to the first_or_create
call.
require 'planter'
class UsersSeeder < Planter::Seeder
seeding_method :data_array, unique_columns: %i[username email]
def data
['foo', email: 'bar', password: 'Example']
end
end
If you need to seed a different way, put your own custom seed method in
your seeder class and do whatever needs to be done.
Constant Summary collapse
- SEEDING_METHODS =
The allowed seeding methods.
%i[csv data_array].freeze
Instance Attribute Summary collapse
-
#data ⇒ Array
readonly
Array of hashes used to create records.
-
#transformations ⇒ Hash?
readonly
A hash of user-defined column names and procs to be run on values.
Class Method Summary collapse
-
.default_table_name ⇒ String
Return the table name inferred from the seeder class name.
-
.seeding_method(seed_method, number_of_records: 1, table: nil, parent: nil, csv_name: nil, unique_columns: nil, erb_trim_mode: nil) ⇒ Object
If your class is going to use the inherited
seedmethod, you must tell it whichseeding_methodto use.
Instance Method Summary collapse
-
#csv_name ⇒ String
The CSV file corresponding to the table.
-
#erb_trim_mode ⇒ String
What trim mode should ERB use?.
-
#number_of_records ⇒ Integer
The number of records to create from each record in the
dataarray. -
#parent ⇒ String
Adapter-defined parent relation.
-
#seed ⇒ Object
The default seed method.
-
#seed_method ⇒ Symbol
The seeding method specified.
-
#table_name ⇒ String
The table being seeded.
-
#unique_columns ⇒ Array
When creating a record, the fields that will be used to look up the record.
Instance Attribute Details
#data ⇒ Array (readonly)
Array of hashes used to create records. Your class must set this
attribute when using data_array seeding method, although it's probably
more likely that you'll want to define a method that returns a new set of
data each time (via Faker, Array#sample, etc.). When using csv,
data will be set to the data within the CSV. You can override this.
107 108 109 |
# File 'lib/planter/seeder.rb', line 107 def data @data end |
#transformations ⇒ Hash? (readonly)
A hash of user-defined column names and procs to be run on values. This is most useful for when seeding from CSV, and you need to transform, say, 'true' (String) into true (Boolean). The user may define this as an instance variable, or define a method that returns the hash.
When defining a Proc/Lambda, you can make it accept 0, 1, or 2 arguments.
- When 0, the value is replaced by the result of the Lambda.
- When 1, the value is passed to the Lambda, and is subsequently replaced by the result of the Lambda.
- When 2, the value is the first argument, and the entire row, as a Hash, is the second argument. This allows for more complicated transformations that can be dependent on other fields and values in the record.
136 137 138 |
# File 'lib/planter/seeder.rb', line 136 def transformations @transformations end |
Class Method Details
.default_table_name ⇒ String
Return the table name inferred from the seeder class name.
245 246 247 |
# File 'lib/planter/seeder.rb', line 245 def self.default_table_name to_s.delete_suffix("Seeder").underscore end |
.seeding_method(seed_method, number_of_records: 1, table: nil, parent: nil, csv_name: nil, unique_columns: nil, erb_trim_mode: nil) ⇒ Object
If your class is going to use the inherited seed method, you must tell
it which seeding_method to use. The argument to this method must be
included in the SEEDING_METHODS array.
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/planter/seeder.rb', line 215 def self.seeding_method( seed_method, number_of_records: 1, table: nil, parent: nil, csv_name: nil, unique_columns: nil, erb_trim_mode: nil ) unless SEEDING_METHODS.include?(seed_method.intern) raise ArgumentError, "Method must be: #{SEEDING_METHODS.join(", ")}" end self.seed_method = seed_method self.number_of_records = number_of_records self.table_name = (table || default_table_name).to_s self.parent = parent self.csv_name = (csv_name || table_name).to_s self.erb_trim_mode = erb_trim_mode || Planter.config.erb_trim_mode self.unique_columns = case unique_columns when String, Symbol then [unique_columns.intern] when Array then unique_columns.map(&:intern) end end |
Instance Method Details
#csv_name ⇒ String
The CSV file corresponding to the table.
177 |
# File 'lib/planter/seeder.rb', line 177 class_attribute :csv_name |
#erb_trim_mode ⇒ String
What trim mode should ERB use?
142 |
# File 'lib/planter/seeder.rb', line 142 class_attribute :erb_trim_mode |
#number_of_records ⇒ Integer
The number of records to create from each record in the data array. If
nil, defaults to 1, but you can override this in your class via
seeding_method.
171 |
# File 'lib/planter/seeder.rb', line 171 class_attribute :number_of_records |
#parent ⇒ String
Adapter-defined parent relation. Records in the data array will be
created for each record in the parent relation.
163 |
# File 'lib/planter/seeder.rb', line 163 class_attribute :parent |
#seed ⇒ Object
The default seed method. To use this method, your class must provide a
valid seeding_method, and not implement its own seed method.
252 253 254 255 256 257 |
# File 'lib/planter/seeder.rb', line 252 def seed validate_attributes extract_data_from_csv if context.seed_method == :csv context.parent ? create_records_from_parent : create_records end |
#seed_method ⇒ Symbol
The seeding method specified.
183 |
# File 'lib/planter/seeder.rb', line 183 class_attribute :seed_method |
#table_name ⇒ String
The table being seeded. If the table name you need is different, change
via seeding_method.
156 |
# File 'lib/planter/seeder.rb', line 156 class_attribute :table_name |
#unique_columns ⇒ Array
When creating a record, the fields that will be used to look up the record. If it already exists, a new one will not be created.
149 |
# File 'lib/planter/seeder.rb', line 149 class_attribute :unique_columns |