seed-fu 1.2.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +38 -0
- data/LICENSE +20 -0
- data/README.md +149 -0
- data/lib/seed-fu.rb +29 -86
- data/lib/seed-fu/active_record_extension.rb +71 -0
- data/lib/seed-fu/block_hash.rb +21 -0
- data/lib/seed-fu/railtie.rb +14 -0
- data/lib/seed-fu/runner.rb +73 -0
- data/lib/seed-fu/seeder.rb +77 -0
- data/lib/seed-fu/version.rb +4 -0
- data/lib/seed-fu/writer.rb +132 -3
- data/lib/tasks/seed_fu.rake +43 -0
- metadata +75 -32
- data/README.rdoc +0 -125
- data/Rakefile +0 -34
- data/VERSION +0 -1
- data/lib/seed-fu/writer/abstract.rb +0 -58
- data/lib/seed-fu/writer/seed.rb +0 -26
- data/lib/seed-fu/writer/seed_many.rb +0 -52
- data/rails/init.rb +0 -1
- data/spec/schema.rb +0 -8
- data/spec/seed_fu_spec.rb +0 -116
- data/spec/spec_helper.rb +0 -8
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
|
3
|
+
module SeedFu
|
4
|
+
# Creates or updates seed records with data.
|
5
|
+
#
|
6
|
+
# It is not recommended to use this class directly. Instead, use `Model.seed`, and `Model.seed_once`,
|
7
|
+
# where `Model` is your Active Record model.
|
8
|
+
#
|
9
|
+
# @see ActiveRecordExtension
|
10
|
+
class Seeder
|
11
|
+
# @param [ActiveRecord::Base] model_class The model to be seeded
|
12
|
+
# @param [Array<Symbol>] constraints A list of attributes which identify a particular seed. If
|
13
|
+
# a record with these attributes already exists then it will be updated rather than created.
|
14
|
+
# @param [Array<Hash>] data Each item in this array is a hash containing attributes for a
|
15
|
+
# particular record.
|
16
|
+
# @param [Hash] options
|
17
|
+
# @option options [Boolean] :quiet (SeedFu.quiet) If true, output will be silenced
|
18
|
+
# @option options [Boolean] :insert_only (false) If true then existing records which match the
|
19
|
+
# constraints will not be updated, even if the seed data has changed
|
20
|
+
def initialize(model_class, constraints, data, options = {})
|
21
|
+
@model_class = model_class
|
22
|
+
@constraints = constraints.to_a.empty? ? [:id] : constraints
|
23
|
+
@data = data.to_a || []
|
24
|
+
@options = options.symbolize_keys
|
25
|
+
|
26
|
+
@options[:quiet] ||= SeedFu.quiet
|
27
|
+
|
28
|
+
validate_constraints!
|
29
|
+
validate_data!
|
30
|
+
end
|
31
|
+
|
32
|
+
# Insert/update the records as appropriate. Validation is skipped while saving.
|
33
|
+
# @return [Array<ActiveRecord::Base>] The records which have been seeded
|
34
|
+
def seed
|
35
|
+
@model_class.transaction do
|
36
|
+
@data.map { |record_data| seed_record(record_data.symbolize_keys) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def validate_constraints!
|
43
|
+
unknown_columns = @constraints.map(&:to_s) - @model_class.column_names
|
44
|
+
unless unknown_columns.empty?
|
45
|
+
raise(ArgumentError,
|
46
|
+
"Your seed constraints contained unknown columns: #{column_list(unknown_columns)}. " +
|
47
|
+
"Valid columns are: #{column_list(@model_class.column_names)}.")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate_data!
|
52
|
+
raise ArgumentError, "Seed data missing" if @data.empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
def column_list(columns)
|
56
|
+
'`' + columns.join("`, `") + '`'
|
57
|
+
end
|
58
|
+
|
59
|
+
def seed_record(data)
|
60
|
+
record = find_or_initialize_record(data)
|
61
|
+
return if @options[:insert_only] && !record.new_record?
|
62
|
+
record.send(:attributes=, data, false)
|
63
|
+
puts " - #{@model_class} #{data.inspect}" unless @options[:quiet]
|
64
|
+
record.save(:validate => false)
|
65
|
+
record
|
66
|
+
end
|
67
|
+
|
68
|
+
def find_or_initialize_record(data)
|
69
|
+
@model_class.where(constraint_conditions(data)).first ||
|
70
|
+
@model_class.new
|
71
|
+
end
|
72
|
+
|
73
|
+
def constraint_conditions(data)
|
74
|
+
Hash[@constraints.map { |c| [c, data[c.to_sym]] }]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/seed-fu/writer.rb
CHANGED
@@ -1,3 +1,132 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module SeedFu
|
2
|
+
# {Writer} is used to programmatically generated seed files. For example, you might want to write
|
3
|
+
# a script which converts data in a CSV file to a valid Seed Fu seed file, which can then be
|
4
|
+
# imported.
|
5
|
+
#
|
6
|
+
# @example Basic usage
|
7
|
+
# SeedFu::Writer.write('path/to/file.rb', :class_name => 'Person', :constraints => [:first_name, :last_name]) do |writer|
|
8
|
+
# writer.write(:first_name => 'Jon', :last_name => 'Smith', :age => 21)
|
9
|
+
# writer.write(:first_name => 'Emily', :last_name => 'McDonald', :age => 24)
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# # Writes the following to the file:
|
13
|
+
# #
|
14
|
+
# # Person.seed(:first_name, :last_name,
|
15
|
+
# # {:first_name=>"Jon", :last_name=>"Smith", :age=>21},
|
16
|
+
# # {:first_name=>"Emily", :last_name=>"McDonald", :age=>24}
|
17
|
+
# # )
|
18
|
+
class Writer
|
19
|
+
cattr_accessor :default_options
|
20
|
+
@@default_options = {
|
21
|
+
:chunk_size => 100,
|
22
|
+
:constraints => [:id],
|
23
|
+
:seed_type => :seed
|
24
|
+
}
|
25
|
+
|
26
|
+
# @param [Hash] options
|
27
|
+
# @option options [String] :class_name *Required* The name of the Active Record model to
|
28
|
+
# generate seeds for
|
29
|
+
# @option options [Fixnum] :chunk_size (100) The number of seeds to write before generating a
|
30
|
+
# `# BREAK EVAL` line. (Chunking reduces memory usage when loading seeds.)
|
31
|
+
# @option options [:seed, :seed_once] :seed_type (:seed) The method to use when generating
|
32
|
+
# seeds. See {ActiveRecordExtension} for details.
|
33
|
+
# @option options [Array<Symbol>] :constraints ([:id]) The constraining attributes for the seeds
|
34
|
+
def initialize(options = {})
|
35
|
+
@options = self.class.default_options.merge(options)
|
36
|
+
raise ArgumentError, "missing option :class_name" unless @options[:class_name]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Creates a new instance of {Writer} with the `options`, and then calls {#write} with the
|
40
|
+
# `io_or_filename` and `block`
|
41
|
+
def self.write(io_or_filename, options = {}, &block)
|
42
|
+
new(options).write(io_or_filename, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Writes the necessary headers and footers, and yields to a block within which the actual
|
46
|
+
# seed data should be writting using the `#<<` method.
|
47
|
+
#
|
48
|
+
# @param [IO] io_or_filename The IO to which writes will be made. (If an `IO` is given, it is
|
49
|
+
# your responsibility to close it after writing.)
|
50
|
+
# @param [String] io_or_filename The filename of a file to make writes to. (Will be opened and
|
51
|
+
# closed automatically.)
|
52
|
+
# @yield [self] make calls to `#<<` within the block
|
53
|
+
def write(io_or_filename, &block)
|
54
|
+
raise ArgumentError, "missing block" unless block_given?
|
55
|
+
|
56
|
+
if io_or_filename.respond_to?(:write)
|
57
|
+
write_to_io(io_or_filename, &block)
|
58
|
+
else
|
59
|
+
File.open(io_or_filename, 'w') do |file|
|
60
|
+
write_to_io(file, &block)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Add a seed. Must be called within a block passed to {#write}.
|
66
|
+
# @param [Hash] seed The attributes for the seed
|
67
|
+
def <<(seed)
|
68
|
+
raise "You must add seeds inside a SeedFu::Writer#write block" unless @io
|
69
|
+
|
70
|
+
buffer = ''
|
71
|
+
|
72
|
+
if chunk_this_seed?
|
73
|
+
buffer << seed_footer
|
74
|
+
buffer << "# BREAK EVAL\n"
|
75
|
+
buffer << seed_header
|
76
|
+
end
|
77
|
+
|
78
|
+
buffer << ",\n"
|
79
|
+
buffer << ' ' + seed.inspect
|
80
|
+
|
81
|
+
@io.write(buffer)
|
82
|
+
|
83
|
+
@count += 1
|
84
|
+
end
|
85
|
+
alias_method :add, :<<
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def write_to_io(io)
|
90
|
+
@io, @count = io, 0
|
91
|
+
@io.write(file_header)
|
92
|
+
@io.write(seed_header)
|
93
|
+
yield(self)
|
94
|
+
@io.write(seed_footer)
|
95
|
+
@io.write(file_footer)
|
96
|
+
ensure
|
97
|
+
@io, @count = nil, nil
|
98
|
+
end
|
99
|
+
|
100
|
+
def file_header
|
101
|
+
<<-END
|
102
|
+
# DO NOT MODIFY THIS FILE, it was auto-generated.
|
103
|
+
#
|
104
|
+
# Date: #{Time.now}
|
105
|
+
# Seeding #{@options[:class_name]}
|
106
|
+
# Written with the command:
|
107
|
+
#
|
108
|
+
# #{$0} #{$*.join}
|
109
|
+
#
|
110
|
+
END
|
111
|
+
end
|
112
|
+
|
113
|
+
def file_footer
|
114
|
+
<<-END
|
115
|
+
# End auto-generated file.
|
116
|
+
END
|
117
|
+
end
|
118
|
+
|
119
|
+
def seed_header
|
120
|
+
constraints = @options[:constraints] && @options[:constraints].map(&:inspect).join(', ')
|
121
|
+
"#{@options[:class_name]}.#{@options[:seed_type]}(#{constraints}"
|
122
|
+
end
|
123
|
+
|
124
|
+
def seed_footer
|
125
|
+
"\n)\n"
|
126
|
+
end
|
127
|
+
|
128
|
+
def chunk_this_seed?
|
129
|
+
@count != 0 && (@count % @options[:chunk_size]) == 0
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'seed-fu'
|
2
|
+
|
3
|
+
namespace :db do
|
4
|
+
desc <<-EOS
|
5
|
+
Loads seed data for the current environment. It will look for
|
6
|
+
ruby seed files in <RAILS_ROOT>/db/fixtures/ and
|
7
|
+
<RAILS_ROOT>/db/fixtures/<RAILS_ENV>/.
|
8
|
+
|
9
|
+
By default it will load any ruby files found. You can filter the files
|
10
|
+
loaded by passing in the FILTER environment variable with a comma-delimited
|
11
|
+
list of patterns to include. Any files not matching the pattern will
|
12
|
+
not be loaded.
|
13
|
+
|
14
|
+
You can also change the directory where seed files are looked for
|
15
|
+
with the FIXTURE_PATH environment variable.
|
16
|
+
|
17
|
+
Examples:
|
18
|
+
# default, to load all seed files for the current environment
|
19
|
+
rake db:seed
|
20
|
+
|
21
|
+
# to load seed files matching orders or customers
|
22
|
+
rake db:seed FILTER=orders,customers
|
23
|
+
|
24
|
+
# to load files from RAILS_ROOT/features/fixtures
|
25
|
+
rake db:seed FIXTURE_PATH=features/fixtures
|
26
|
+
EOS
|
27
|
+
task :seed_fu => :environment do
|
28
|
+
if ENV["SEED"]
|
29
|
+
puts "DEPRECATED: The SEED option to db:seed_fu is deprecated. Please use FILTER instead."
|
30
|
+
ENV["FILTER"] = ENV["SEED"]
|
31
|
+
end
|
32
|
+
|
33
|
+
if ENV["FILTER"]
|
34
|
+
filter = /#{ENV["FILTER"].gsub(/,/, "|")}/
|
35
|
+
end
|
36
|
+
|
37
|
+
if ENV["FIXTURE_PATH"]
|
38
|
+
fixture_paths = [ENV["FIXTURE_PATH"], ENV["FIXTURE_PATH"] + '/' + Rails.env]
|
39
|
+
end
|
40
|
+
|
41
|
+
SeedFu.seed(fixture_paths, filter)
|
42
|
+
end
|
43
|
+
end
|
metadata
CHANGED
@@ -1,77 +1,120 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seed-fu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 2
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 2.0.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Michael Bleigh
|
13
|
+
- Jon Leighton
|
8
14
|
autorequire:
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-11-05 00:00:00 +00:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
22
|
+
name: activerecord
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 3
|
31
|
+
- 0
|
32
|
+
- 0
|
33
|
+
version: 3.0.0
|
17
34
|
type: :runtime
|
18
|
-
|
19
|
-
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
segments:
|
45
|
+
- 2
|
46
|
+
- 0
|
47
|
+
- 0
|
48
|
+
version: 2.0.0
|
49
|
+
type: :development
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: sqlite3
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
20
56
|
requirements:
|
21
57
|
- - ">="
|
22
58
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
type: :development
|
63
|
+
version_requirements: *id003
|
25
64
|
description: Seed Fu is an attempt to once and for all solve the problem of inserting and maintaining seed data in a database. It uses a variety of techniques gathered from various places around the web and combines them to create what is hopefully the most robust seed data system around.
|
26
|
-
email:
|
65
|
+
email:
|
66
|
+
- michael@intridea.com
|
67
|
+
- j@jonathanleighton.com
|
27
68
|
executables: []
|
28
69
|
|
29
70
|
extensions: []
|
30
71
|
|
31
|
-
extra_rdoc_files:
|
32
|
-
|
72
|
+
extra_rdoc_files: []
|
73
|
+
|
33
74
|
files:
|
34
|
-
-
|
35
|
-
-
|
36
|
-
-
|
37
|
-
- lib/seed-fu.rb
|
75
|
+
- lib/tasks/seed_fu.rake
|
76
|
+
- lib/seed-fu/block_hash.rb
|
77
|
+
- lib/seed-fu/runner.rb
|
78
|
+
- lib/seed-fu/active_record_extension.rb
|
79
|
+
- lib/seed-fu/seeder.rb
|
80
|
+
- lib/seed-fu/railtie.rb
|
81
|
+
- lib/seed-fu/version.rb
|
38
82
|
- lib/seed-fu/writer.rb
|
39
|
-
- lib/seed-fu
|
40
|
-
-
|
41
|
-
-
|
42
|
-
-
|
43
|
-
- spec/schema.rb
|
44
|
-
- spec/seed_fu_spec.rb
|
45
|
-
- spec/spec_helper.rb
|
83
|
+
- lib/seed-fu.rb
|
84
|
+
- LICENSE
|
85
|
+
- README.md
|
86
|
+
- CHANGELOG.md
|
46
87
|
has_rdoc: true
|
47
|
-
homepage: http://github.com/
|
88
|
+
homepage: http://github.com/mbleigh/seed-fu
|
48
89
|
licenses: []
|
49
90
|
|
50
91
|
post_install_message:
|
51
|
-
rdoc_options:
|
52
|
-
|
92
|
+
rdoc_options: []
|
93
|
+
|
53
94
|
require_paths:
|
54
95
|
- lib
|
55
96
|
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
56
98
|
requirements:
|
57
99
|
- - ">="
|
58
100
|
- !ruby/object:Gem::Version
|
101
|
+
segments:
|
102
|
+
- 0
|
59
103
|
version: "0"
|
60
|
-
version:
|
61
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
62
106
|
requirements:
|
63
107
|
- - ">="
|
64
108
|
- !ruby/object:Gem::Version
|
109
|
+
segments:
|
110
|
+
- 0
|
65
111
|
version: "0"
|
66
|
-
version:
|
67
112
|
requirements: []
|
68
113
|
|
69
114
|
rubyforge_project:
|
70
|
-
rubygems_version: 1.3.
|
115
|
+
rubygems_version: 1.3.7
|
71
116
|
signing_key:
|
72
117
|
specification_version: 3
|
73
|
-
summary:
|
74
|
-
test_files:
|
75
|
-
|
76
|
-
- spec/seed_fu_spec.rb
|
77
|
-
- spec/spec_helper.rb
|
118
|
+
summary: Easily manage seed data in your Active Record application
|
119
|
+
test_files: []
|
120
|
+
|
data/README.rdoc
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
= Seed Fu
|
2
|
-
|
3
|
-
Seed Fu is an attempt to once and for all solve the problem of inserting and maintaining seed data in a database. It uses a variety of techniques gathered from various places around the web and combines them to create what is hopefully the most robust seed data system around.
|
4
|
-
|
5
|
-
|
6
|
-
== Simple Usage
|
7
|
-
|
8
|
-
Seed data is taken from the <tt>db/fixtures</tt> directory. Simply make descriptive .rb files in that directory (they can be named anything, but users.rb for the User model seed data makes sense, etc.). These scripts will be run whenever the <tt>db:seed</tt> (<tt>db:seed_fu</tt> for Rails 2.3.5 and greater) rake task is called, and in order (you can use <tt>00_first.rb</tt>, <tt>00_second.rb</tt>, etc). You can put arbitrary Ruby code in these files, but remember that it will be executed every time the rake task is called, so it needs to be runnable multiple times on the same database.
|
9
|
-
|
10
|
-
You can also have environment-specific seed data placed in <tt>db/fixtures/ENVIRONMENT</tt> that will only be loaded if that is the current environment.
|
11
|
-
|
12
|
-
Let's say we want to populate a few default users. In <tt>db/fixtures/users.rb</tt> we write the following code:
|
13
|
-
|
14
|
-
User.seed(:login, :email) do |s|
|
15
|
-
s.login = "bob"
|
16
|
-
s.email = "bob@bobson.com"
|
17
|
-
s.first_name = "Bob"
|
18
|
-
s.last_name = "Bobson"
|
19
|
-
end
|
20
|
-
|
21
|
-
User.seed(:login, :email) do |s|
|
22
|
-
s.login = "bob"
|
23
|
-
s.email = "bob@stevenson.com"
|
24
|
-
s.first_name = "Bob"
|
25
|
-
s.last_name = "Stevenson"
|
26
|
-
end
|
27
|
-
|
28
|
-
That's all you have to do! You will now have two users created in the system and you can change their first and last names in the users.rb file and it will be updated as such.
|
29
|
-
|
30
|
-
The arguments passed to the <tt><ActiveRecord>.seed</tt> method are the constraining attributes: these must remain unchanged between db:seed calls to avoid data duplication. By default, seed data will constrain to the id like so:
|
31
|
-
|
32
|
-
Category.seed do |s|
|
33
|
-
s.id = 1
|
34
|
-
s.name = "Buttons"
|
35
|
-
end
|
36
|
-
|
37
|
-
Category.seed do |s|
|
38
|
-
s.id = 2
|
39
|
-
s.name = "Bobbins"
|
40
|
-
s.parent_id = 1
|
41
|
-
end
|
42
|
-
|
43
|
-
Note that any constraints that are passed in must be present in the subsequent seed data setting.
|
44
|
-
|
45
|
-
== Seed-many Usage
|
46
|
-
|
47
|
-
The default <tt>.seed` syntax is very verbose. An alternative is the `.seed_many</tt> syntax. Look at this refactoring of the first seed usage example above:
|
48
|
-
|
49
|
-
User.seed_many(:login, :email, [
|
50
|
-
{ :login => "bob", :email => "bob@bobson.com", :first_name => "Bob", :last_name = "Bobson" },
|
51
|
-
{ :login => "bob", :email => "bob@stevenson.com", :first_name => "Bob", :last_name = "Stevenson" }
|
52
|
-
])
|
53
|
-
|
54
|
-
Not as pretty, but much more concise.
|
55
|
-
|
56
|
-
== Handling Large SeedFu Files
|
57
|
-
|
58
|
-
Seed files can be huge. To handle large files (over a million rows), try these tricks:
|
59
|
-
|
60
|
-
* Gzip your fixtures. Seed Fu will read .rb.gz files happily. <tt>gzip -9</tt> gives the best compression, and with Seed Fu's repetitive syntax, a 160M file can shrink to 16M.
|
61
|
-
* Add lines reading <tt># BREAK EVAL</tt> in your big fixtures, and Seed Fu will avoid loading the whole file into memory. If you use SeedFu::Writer, these breaks are built into your generated fixtures.
|
62
|
-
* Load a single fixture with the <tt>SEED</tt> environment variable: <tt>SEED=cities,states rake db:seed > seed_log`. Each argument to `SEED</tt> is used as a regex to filter fixtures by filename.
|
63
|
-
|
64
|
-
== Generating SeedFu Files
|
65
|
-
|
66
|
-
Say you have a CSV you need to massage and store as seed files. You can create an import script using SeedFu::Writer.
|
67
|
-
|
68
|
-
#!/usr/bin/env ruby
|
69
|
-
#
|
70
|
-
# This is: script/generate_cities_seed_from_csv
|
71
|
-
#
|
72
|
-
require 'rubygems'
|
73
|
-
require 'fastercsv'
|
74
|
-
require File.join( File.dirname(__FILE__), '..', 'vendor/plugins/seed-fu/lib/seed-fu/writer' )
|
75
|
-
|
76
|
-
# Maybe SEEF_FILE could be $stdout, hm.
|
77
|
-
#
|
78
|
-
CITY_CSV = File.join( File.dirname(__FILE__), '..', 'city.csv' )
|
79
|
-
SEED_FILE = File.join( File.dirname(__FILE__), '..', 'db', 'fixtures', 'cities.rb' )
|
80
|
-
|
81
|
-
# Create a seed_writer, walk the CSV, add to the file.
|
82
|
-
#
|
83
|
-
|
84
|
-
seed_writer = SeedFu::Writer::SeedMany.new(
|
85
|
-
:seed_file => SEED_FILE,
|
86
|
-
:seed_model => 'City',
|
87
|
-
:seed_by => [ :city, :state ]
|
88
|
-
)
|
89
|
-
|
90
|
-
FasterCSV.foreach( CITY_CSV,
|
91
|
-
:return_headers => false,
|
92
|
-
:headers => :first_row
|
93
|
-
) do |row|
|
94
|
-
|
95
|
-
# Skip all but the US
|
96
|
-
#
|
97
|
-
next unless row['country_code'] == 'US'
|
98
|
-
|
99
|
-
unless us_state
|
100
|
-
puts "No State Match for #{row['region_name']}"
|
101
|
-
next
|
102
|
-
end
|
103
|
-
|
104
|
-
# Write the seed
|
105
|
-
#
|
106
|
-
seed_writer.add_seed({
|
107
|
-
:zip => row['zipcode'],
|
108
|
-
:state => row['state'],
|
109
|
-
:city => row['city'],
|
110
|
-
:latitude => row['latitude'],
|
111
|
-
:longitude => row['longitude']
|
112
|
-
})
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
seed_writer.finish
|
117
|
-
|
118
|
-
There is also a SeedFu::Writer::Seed in case you prefere the seed()
|
119
|
-
syntax over the seen_many() syntax. Easy-peasy.
|
120
|
-
|
121
|
-
== Contributors
|
122
|
-
|
123
|
-
* Thanks to Matthew Beale for his great work in adding the writer, making it faster and better.
|
124
|
-
|
125
|
-
Copyright (c) 2008-2009 Michael Bleigh released under the MIT license
|