README.md in data_seeder-0.0.5 vs README.md in data_seeder-1.0.0

- old
+ new

@@ -36,34 +36,33 @@ t.string :name, null: false end And you have a corresponding db/seed/countries.txt file as follows: - # config: { key_attribute: 'code', line: ->(line) { { code: line[0,2], name: line[3...-1] } } } AD Andorra AE United Arab Emirates AF Arghanistan -The first line in a file can define the config attributes associated with the file. For this seed file, -the key_attribute says that it will use the 'code' attribute to lookup existing records (defaults to 'id') -and the line function -defines how the line is converted to an attribute hash defining the instance. +And a db/seed/countries.cfg file as follows: -Since the first line can get a little busy with config information, you can also store your config in a -separate .cfg file with the same name. This contents of this file should eval to a hash. The above config line would be -equivalent to a db/seed/countries.cfg file with the following: - { - key_attribute: :'code', - line: ->(attr) { + key_attribute: 'code', + line: ->(line) { { code: line[0,2], name: line[3...-1] } } } +The cfg file defines the config attributes associated with the file. This contents of this file +should eval to a hash. For this seed file, +the key_attribute says that it will use the 'code' attribute to lookup existing records (defaults to 'id') +and the line function +defines how the line is converted to an attribute hash defining the instance. + + Running rake db:seed will result in the following output: # rake db:seed Loading countries Saving #<Country id: 1, code: "AD", name: "Andorra"> @@ -95,15 +94,15 @@ data_seeder has default loaders for txt, csv, json and yml extensions but you can also create your own custom loaders. For instance, suppose you had the following tables: ```ruby -create_table "apps", force: :cascade do |t| +create_table "apps" do |t| t.string "name" end -create_table "app_errors", force: :cascade do |t| +create_table "app_errors" do |t| t.integer "app_id" t.string "code" t.string "message" end add_index "app_errors", ["app_id"], name: "index_app_errors_on_app_id" @@ -120,73 +119,18 @@ A1 Error message for A1 A2 Error message for A2 B1 Error message for B1 -You could create your own custom loader that might look as follows: +Look [here](test/dummy/app/models/app_error_data_seeder.rb) for an example of creating your own custom loader. -```ruby -require 'data_seeder' +To add this seeder, you would create the following config/initializers/data_seeder.rb: -class AppErrorDataSeeder - include ::DataSeeder::Loader - - def setup - @app = App.find_or_initialize_by(name: self.path_minus_ext) - @existing_errors = {} - if @app.new_record? - logger.info "Loading errors for new App: #{@app.name}" - @app.save! - else - logger.info "Loading errors for existing App: #{@app.name}" - @app.app_errors.each do |app_error| - @existing_errors[app_error.code] = app_error - end - end - end - - def teardown - unless @existing_errors.empty? - logger.info { " The following are begin removed:" } - @existing_errors.each do |code, app_error| - logger.info " #{code}: #{app_error.message}" - app_error.destroy - end - end - end - - def load(io) - io.each_line do |line| - line.strip! - next if line.blank? || line[0] == ?# - space_i = line.index(' ') - raise "Invalid line: #{line}" unless space_i - code = line[0,space_i].strip - message = line[space_i+1..-1].strip - app_error = @existing_errors[code] - if app_error - @existing_errors.delete(code) - app_error.message = message - unless app_error.changes.empty? - logger.info { " Changing #{code}: #{app_error.changes}" } - app_error.save! - end - else - logger.info { " Creating #{code}: #{message}" } - @app.app_errors.create!(code: code, message: message) - end - end - end -end -``` - -To add the seeder, you would create the following config/initializers/data_seeder.rb: - ```ruby MyApp::Application.config.after_initialize do DataSeeder.configure do |config| - config.add_loader('err', AppErrorDataSeeder.new) + config.add_loader('err', AppErrorDataSeeder) end end ``` Executing DataSeeder.run would result in the following: @@ -198,48 +142,77 @@ Loading errors for new App: foo Creating 1: Something went wrong Creating 2: We are seriously foobared Creating 3: We are less seriously foobared -TODO ----- +## Configurable values -Ability to specify more than 1 directory for Rails.env overrides. Could potentially be used if you have that -x Gigabyte seed file that you don't want to check into source control and only want run on production? +#### depends -YAML should allow loading as either array or hash. (currently only does hash) +Value or array that this model depends on such that they must be seeded first. Examples: -CSV should have options such as only: and except: for using/skipping the specified header columns. + { + depends: ['countries','states'] + } -The structure.sql caching within rails uses the file timestamp to determine whether to prepare the test database. This -is error prone and forces you to do a 'touch db/structure.sql' to get around the not getting reloaded problem. Should -I add a utility to override this rails implementation with a sha-based one like the seed files use? (or am I the only -one who has to 'touch db/structure.sql' everytime I switch branches?) +#### key_attribute -Add 'sql' loader (with disclaimer that it will temporarily truncate the table) +The attribute used to define uniqueness within the model. Can be a single attribute or an array. Defaults to 'id' -Ability to stop early when loading up a large seed file for a given environment, i.e., stop after processing the -first 10 lines when Rails.env.test? +#### klass -I want to allow different seeding for different environments. For instance development might have a bunch of dummy -data useful for getting an environment up and running. I'm thinking either the seed_dir similar to like a PATH -environment variable where the first one found would override the others, or maybe make it automatic based on the -directory names and the environment (seed.development/state.yml would override seed/state.yml). +Defines the ActiveRecord Class if it can't be inferred from the seed file. -The test environment will be the one that will constantly being seeded after migrations or branch changes. Some of -the seed files might be large and take a long time to seed. The above -strategy using seed.test might be useful but it might also be useful to have a preprocessor type such as .sh so for -instance you might have seed.test/table_with_lotsa_rows.csv.sh which might consist of the line -'head -20 ../seed/table_with_lotsa_rows.csv' +#### line -Caching of long-running stuff via pg_dump, mysqldump, or other? This belongs with discussion of the environment-specific -seeding above. +Proc used for converting a line to attributes (txt files only). -Allow config-driven initialization so that we could require: false in the Gemfile and only load as needed. +#### postprocess -Add depends_on option. +Modify the attributes from the seed file before applying them to the model. +Example: + + { + key_attribute: 'code', + postprocess: ->(attrs) { + { + code: attrs['country_code'], + name: attrs['country'] + } + } + } + +#### purge + +Destroys rows that no longer exist in the seed file. + +#### update_display_method + +Model method used for displaying updates to a model. + +#### use_line_number_as_id + +Use the line number of the seed file as the id + +## Incompatibilities from 0.0.x version + +Custom seeders should now be specified as a Class and not an instance (MySeeder instead of MySeeder.new) + +data_seeder_<config-item> methods within the models are no longer supported. + +Using the first line of txt, json, and yaml files as the config is no longer supported. Move them to +a separate .cfg file. + + +TODO +---- + +Add 'sql' loader (with disclaimer that it will temporarily truncate the table) + +Caching of long-running stuff via pg_dump, mysqldump, or other? + Document options (key_attribute, line, postprocess, etc) Meta ---- @@ -256,10 +229,10 @@ [Brad Pardee](https://github.com/bpardee) License ------- -Copyright 2015 Brad Pardee +Copyright 2015-2016 Brad Pardee Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at