seed_dump 1.0.0 → 2.0.0
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 +4 -4
- data/Gemfile +5 -0
- data/README.md +9 -17
- data/VERSION +1 -1
- data/lib/seed_dump.rb +5 -3
- data/lib/seed_dump/dump_methods.rb +151 -0
- data/lib/seed_dump/railtie.rb +2 -2
- data/lib/tasks/seed_dump.rake +1 -1
- data/seed_dump.gemspec +8 -8
- data/spec/helpers.rb +69 -0
- data/spec/seed_dump_spec.rb +157 -0
- data/spec/spec_helper.rb +22 -7
- metadata +19 -8
- data/lib/seed_dump/perform.rb +0 -201
- data/spec/models/abstract_sample.rb +0 -3
- data/spec/models/child_sample.rb +0 -3
- data/spec/models/nested/sample.rb +0 -2
- data/spec/models/sample.rb +0 -2
- data/spec/seed_dump_perform_spec.rb +0 -118
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a7a3bc7780fa30de0f2ffccb171249879058fa5
|
4
|
+
data.tar.gz: dad1c603abb084874344d01263e6dae6d88ea03d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e1f0bfa9e904d6b0b6756b45caa39afee9576f5661c155485d23f430ff87509f488f6b95e247e4ede7f3b41171229b9e49e989677acb3b658be5345e343f4d5
|
7
|
+
data.tar.gz: 74606c3f956c8b5118e83edea597f152e8e02b7913ee1af6ffcba3f9c63f0700d0f34042bfe50f2e536b72b29bfcb1a27d4c58682d9f16926b3699ff7afe1655
|
data/Gemfile
CHANGED
@@ -3,6 +3,10 @@ source 'https://rubygems.org'
|
|
3
3
|
gem 'activesupport'
|
4
4
|
gem 'activerecord'
|
5
5
|
|
6
|
+
group :development, :test do
|
7
|
+
gem 'byebug'
|
8
|
+
end
|
9
|
+
|
6
10
|
group :development do
|
7
11
|
gem 'jeweler', :git => 'git://github.com/technicalpickles/jeweler.git'
|
8
12
|
end
|
@@ -10,4 +14,5 @@ end
|
|
10
14
|
group :test do
|
11
15
|
gem 'rspec'
|
12
16
|
gem 'sqlite3'
|
17
|
+
gem 'database_cleaner'
|
13
18
|
end
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ Seed Dump is a Rails 4 plugin that adds a rake task named `db:seed:dump`.
|
|
5
5
|
|
6
6
|
It allows you to create a `db/seeds.rb` from the existing data in your database.
|
7
7
|
|
8
|
-
Note: if you want to use Seed Dump with Rails 3 or earlier, use [version 0.5.3](http://rubygems.org/gems/seed_dump/versions/0.5.3)
|
8
|
+
Note: if you want to use Seed Dump with Rails 3 or earlier, use [version 0.5.3](http://rubygems.org/gems/seed_dump/versions/0.5.3).
|
9
9
|
|
10
10
|
Example Usage
|
11
11
|
-------------
|
@@ -24,12 +24,12 @@ Result:
|
|
24
24
|
# Autogenerated by the db:seed:dump task
|
25
25
|
# Do not hesitate to tweak this to your needs
|
26
26
|
|
27
|
-
products = Product.create([
|
27
|
+
products = Product.create!([
|
28
28
|
{ :category_id => 1, :description => "Long Sleeve Shirt", :name => "Long Sleeve Shirt" },
|
29
29
|
{ :category_id => 3, :description => "Plain White Tee Shirt", :name => "Plain T-Shirt" }
|
30
30
|
])
|
31
31
|
|
32
|
-
users = User.create([
|
32
|
+
users = User.create!([
|
33
33
|
{ :id => 1, :password => "123456", :username => "test_1" },
|
34
34
|
{ :id => 2, :password => "234567", :username => "tes2" }
|
35
35
|
])
|
@@ -42,9 +42,9 @@ Use another output file instead of `db/seeds.rb`:
|
|
42
42
|
|
43
43
|
rake db:seed:dump FILE=db/categories.rb
|
44
44
|
|
45
|
-
If you want the dump to use `create
|
45
|
+
If you want the dump to use `create` rather than `create!`:
|
46
46
|
|
47
|
-
rake db:seed:dump CREATE_METHOD='create
|
47
|
+
rake db:seed:dump CREATE_METHOD='create'
|
48
48
|
|
49
49
|
There are more environment variables that can be set— see below for all of them.
|
50
50
|
|
@@ -64,9 +64,9 @@ Or install it by hand:
|
|
64
64
|
All environment variables
|
65
65
|
-------------------------
|
66
66
|
|
67
|
-
`APPEND`:
|
67
|
+
`APPEND`: If set to `true`, append the data to the file instead of overwriting it. Default: `false`.
|
68
68
|
|
69
|
-
`CREATE_METHOD`: Use the specified create method rather than `create
|
69
|
+
`CREATE_METHOD`: Use the specified create method rather than `create!` (the default).
|
70
70
|
|
71
71
|
`FILE`: Use a different output file. Default: `db/seeds.rb`.
|
72
72
|
|
@@ -76,14 +76,6 @@ All environment variables
|
|
76
76
|
|
77
77
|
`MODEL[S]`: A model name or a comma-separated list of models. Default: all models.
|
78
78
|
|
79
|
-
`
|
79
|
+
`WITH_ID`: If set to `true`, include the `:id` in the `create` options. Default: `false`.
|
80
80
|
|
81
|
-
`
|
82
|
-
|
83
|
-
`TIMESTAMPS`: If true, include the `:created_by` and `:updated_by` timestamps. If false, don't include them. Default: true.
|
84
|
-
|
85
|
-
`SKIP_CALLBACKS`: Deactivate callbacks while importing.
|
86
|
-
|
87
|
-
`PG_SCHEMA`: Postgres schema support.
|
88
|
-
|
89
|
-
`MODEL_DIR`: Specify an alternate model dir.
|
81
|
+
`TIMESTAMPS`: If set to `true`, include the `:created_by` and `:updated_by` timestamps. Default: `true`.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
data/lib/seed_dump.rb
CHANGED
@@ -0,0 +1,151 @@
|
|
1
|
+
require "true"
|
2
|
+
require "clip"
|
3
|
+
|
4
|
+
class SeedDump
|
5
|
+
module DumpMethods
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@opts = {}
|
9
|
+
@ar_options = {}
|
10
|
+
@indent = ""
|
11
|
+
@models = []
|
12
|
+
@seed_rb = ""
|
13
|
+
@id_set_string = ""
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup(env)
|
17
|
+
# config
|
18
|
+
@opts['verbose'] = env["VERBOSE"].true? || env['VERBOSE'].nil?
|
19
|
+
@opts['debug'] = env["DEBUG"].true?
|
20
|
+
@opts['with_id'] = env["WITH_ID"].true?
|
21
|
+
@opts['timestamps'] = env["TIMESTAMPS"].true? || env["TIMESTAMPS"].nil?
|
22
|
+
@opts['models'] = env['MODELS'] || env['MODEL'] || ""
|
23
|
+
@opts['file'] = env['FILE'] || "#{Rails.root}/db/seeds.rb"
|
24
|
+
@opts['append'] = (env['APPEND'].true? && File.exists?(@opts['file']) )
|
25
|
+
@opts['max'] = env['MAX'] && env['MAX'].to_i > 0 ? env['MAX'].to_i : nil
|
26
|
+
@indent = " " * (env['INDENT'].nil? ? 2 : env['INDENT'].to_i)
|
27
|
+
@opts['create_method'] = env['CREATE_METHOD'] || 'create!'
|
28
|
+
|
29
|
+
@limit = (env['LIMIT'].to_i > 0) ? env['LIMIT'].to_i : nil
|
30
|
+
|
31
|
+
@models = @opts['models'].split(',').collect {|x| x.strip.underscore.singularize.camelize.constantize }
|
32
|
+
end
|
33
|
+
|
34
|
+
def log(msg)
|
35
|
+
puts msg if @opts['debug']
|
36
|
+
end
|
37
|
+
|
38
|
+
def models
|
39
|
+
@models
|
40
|
+
end
|
41
|
+
|
42
|
+
def dump_attribute(a_s, r, k, v)
|
43
|
+
pushed = false
|
44
|
+
if v.is_a?(BigDecimal)
|
45
|
+
v = v.to_s
|
46
|
+
else
|
47
|
+
v = attribute_for_inspect(r,k)
|
48
|
+
end
|
49
|
+
|
50
|
+
unless k == 'id' && !@opts['with_id']
|
51
|
+
if (!(k == 'created_at' || k == 'updated_at') || @opts['timestamps'])
|
52
|
+
a_s.push("#{k.to_sym.inspect} => #{v}")
|
53
|
+
pushed = true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
pushed
|
57
|
+
end
|
58
|
+
|
59
|
+
def dump_model(model)
|
60
|
+
@id_set_string = ''
|
61
|
+
create_hash = ""
|
62
|
+
rows = []
|
63
|
+
|
64
|
+
|
65
|
+
model.find_each(batch_size: (@limit || 1000)) do |record|
|
66
|
+
attr_s = [];
|
67
|
+
|
68
|
+
record.attributes.select {|x| x.is_a?(String) }.each do |k,v|
|
69
|
+
dump_attribute(attr_s, record, k, v)
|
70
|
+
end
|
71
|
+
|
72
|
+
rows.push "#{@indent}{ " << attr_s.join(', ') << " }"
|
73
|
+
|
74
|
+
break if rows.length == @limit
|
75
|
+
end
|
76
|
+
|
77
|
+
if @opts['max']
|
78
|
+
splited_rows = rows.each_slice(@opts['max']).to_a
|
79
|
+
maxsarr = []
|
80
|
+
splited_rows.each do |sr|
|
81
|
+
maxsarr << "\n#{model}.#{@opts['create_method']}([\n" << sr.join(",\n") << "\n])\n"
|
82
|
+
end
|
83
|
+
maxsarr.join('')
|
84
|
+
else
|
85
|
+
"\n#{model}.#{@opts['create_method']}([\n" << rows.join(",\n") << "\n])\n"
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def dump_models
|
91
|
+
if @models.empty?
|
92
|
+
Rails.application.eager_load!
|
93
|
+
|
94
|
+
@seed_rb = ""
|
95
|
+
|
96
|
+
@models = ActiveRecord::Base.descendants.select do |model|
|
97
|
+
(model.to_s != 'ActiveRecord::SchemaMigration') && \
|
98
|
+
model.table_exists? && \
|
99
|
+
model.exists?
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
@models.sort! { |a, b| a.to_s <=> b.to_s }
|
104
|
+
|
105
|
+
@models.each do |model|
|
106
|
+
puts "Adding #{model} seeds." if @opts['verbose']
|
107
|
+
|
108
|
+
@seed_rb << dump_model(model) << "\n\n"
|
109
|
+
end
|
110
|
+
|
111
|
+
@seed_rb
|
112
|
+
end
|
113
|
+
|
114
|
+
def write_file
|
115
|
+
File.open(@opts['file'], (@opts['append'] ? "a" : "w")) { |f|
|
116
|
+
f << "# encoding: utf-8\n"
|
117
|
+
f << "# Autogenerated by the db:seed:dump task\n# Do not hesitate to tweak this to your needs\n" unless @opts['append']
|
118
|
+
f << "#{@seed_rb}"
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
#override the rails version of this function to NOT truncate strings
|
123
|
+
def attribute_for_inspect(r,k)
|
124
|
+
value = r.attributes[k]
|
125
|
+
|
126
|
+
if value.is_a?(String) && value.length > 50
|
127
|
+
"#{value}".inspect
|
128
|
+
elsif value.is_a?(Date) || value.is_a?(Time)
|
129
|
+
%("#{value.to_s(:db)}")
|
130
|
+
else
|
131
|
+
value.inspect
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def output
|
136
|
+
@seed_rb
|
137
|
+
end
|
138
|
+
|
139
|
+
def run(env)
|
140
|
+
setup env
|
141
|
+
|
142
|
+
puts "Appending seeds to #{@opts['file']}." if @opts['append']
|
143
|
+
dump_models
|
144
|
+
|
145
|
+
puts "Writing #{@opts['file']}."
|
146
|
+
write_file
|
147
|
+
|
148
|
+
puts "Done."
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/lib/seed_dump/railtie.rb
CHANGED
data/lib/tasks/seed_dump.rake
CHANGED
data/seed_dump.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "seed_dump"
|
8
|
-
s.version = "
|
8
|
+
s.version = "2.0.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Rob Halff", "Ryan Oblak"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-10-16"
|
13
13
|
s.description = "Dump (parts) of your database to db/seeds.rb to get a headstart creating a meaningful seeds.rb file"
|
14
14
|
s.email = "rroblak@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,16 +25,13 @@ Gem::Specification.new do |s|
|
|
25
25
|
"VERSION",
|
26
26
|
"lib/clip.rb",
|
27
27
|
"lib/seed_dump.rb",
|
28
|
-
"lib/seed_dump/
|
28
|
+
"lib/seed_dump/dump_methods.rb",
|
29
29
|
"lib/seed_dump/railtie.rb",
|
30
30
|
"lib/tasks/seed_dump.rake",
|
31
31
|
"lib/true.rb",
|
32
32
|
"seed_dump.gemspec",
|
33
|
-
"spec/
|
34
|
-
"spec/
|
35
|
-
"spec/models/nested/sample.rb",
|
36
|
-
"spec/models/sample.rb",
|
37
|
-
"spec/seed_dump_perform_spec.rb",
|
33
|
+
"spec/helpers.rb",
|
34
|
+
"spec/seed_dump_spec.rb",
|
38
35
|
"spec/spec_helper.rb"
|
39
36
|
]
|
40
37
|
s.homepage = "https://github.com/rroblak/seed_dump"
|
@@ -48,15 +45,18 @@ Gem::Specification.new do |s|
|
|
48
45
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
46
|
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
50
47
|
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
48
|
+
s.add_development_dependency(%q<byebug>, [">= 0"])
|
51
49
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
52
50
|
else
|
53
51
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
54
52
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
53
|
+
s.add_dependency(%q<byebug>, [">= 0"])
|
55
54
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
56
55
|
end
|
57
56
|
else
|
58
57
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
59
58
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
59
|
+
s.add_dependency(%q<byebug>, [">= 0"])
|
60
60
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
61
61
|
end
|
62
62
|
end
|
data/spec/helpers.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# Mock Rails.application.eager_load! and define some
|
2
|
+
# Rails models for use in specs.
|
3
|
+
class Rails
|
4
|
+
def self.application
|
5
|
+
self
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.eager_load!
|
9
|
+
@already_called ||= false
|
10
|
+
|
11
|
+
if !@already_called
|
12
|
+
Object.const_set('Sample', Class.new(ActiveRecord::Base))
|
13
|
+
|
14
|
+
Object.const_set('AbstractSample', Class.new(ActiveRecord::Base))
|
15
|
+
AbstractSample.abstract_class = true
|
16
|
+
|
17
|
+
Object.const_set('ChildSample', Class.new(AbstractSample))
|
18
|
+
|
19
|
+
Object.const_set('NoTableModel', Class.new(ActiveRecord::Base))
|
20
|
+
|
21
|
+
Object.const_set('Nested', Module.new)
|
22
|
+
Nested.const_set('Sample', Class.new(ActiveRecord::Base))
|
23
|
+
|
24
|
+
Object.const_set('EmptyModel', Class.new(ActiveRecord::Base))
|
25
|
+
|
26
|
+
@already_called = true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module Helpers
|
32
|
+
def create_db
|
33
|
+
ActiveRecord::Migration.verbose = false
|
34
|
+
|
35
|
+
ActiveRecord::Schema.define(:version => 1) do
|
36
|
+
create_table 'child_samples', :force => true do |t|
|
37
|
+
t.string 'name'
|
38
|
+
t.datetime 'created_at', :null => false
|
39
|
+
t.datetime 'updated_at', :null => false
|
40
|
+
end
|
41
|
+
|
42
|
+
create_table 'samples', :force => true do |t|
|
43
|
+
t.string 'string'
|
44
|
+
t.text 'text'
|
45
|
+
t.integer 'integer'
|
46
|
+
t.float 'float'
|
47
|
+
t.decimal 'decimal'
|
48
|
+
t.datetime 'datetime'
|
49
|
+
t.datetime 'timestamp'
|
50
|
+
t.time 'time'
|
51
|
+
t.date 'date'
|
52
|
+
t.binary 'binary'
|
53
|
+
t.boolean 'boolean'
|
54
|
+
t.datetime 'created_at', :null => false
|
55
|
+
t.datetime 'updated_at', :null => false
|
56
|
+
end
|
57
|
+
|
58
|
+
create_table 'empty_models', force: true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def load_sample_data
|
63
|
+
Rails.application.eager_load!
|
64
|
+
|
65
|
+
Sample.create!
|
66
|
+
|
67
|
+
ChildSample.create!
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SeedDump do
|
4
|
+
describe '#dump_models' do
|
5
|
+
before(:all) do
|
6
|
+
create_db
|
7
|
+
end
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
@sd = SeedDump.new
|
11
|
+
|
12
|
+
@env = {'FILE' => Dir.pwd + '/spec/db/seeds.rb',
|
13
|
+
'VERBOSE' => false,
|
14
|
+
'DEBUG' => false}
|
15
|
+
|
16
|
+
ActiveSupport::DescendantsTracker.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should not include timestamps if the TIMESTAMPS parameter is false' do
|
20
|
+
Rails.application.eager_load!
|
21
|
+
|
22
|
+
@env['MODELS'] = 'Sample'
|
23
|
+
@env['TIMESTAMPS'] = false
|
24
|
+
|
25
|
+
@sd.setup @env
|
26
|
+
|
27
|
+
load_sample_data
|
28
|
+
|
29
|
+
@sd.dump_models.should match(/^\nSample\.create!\(\[\n { :string => nil, :text => nil, :integer => nil, :float => nil, :decimal => nil, :datetime => nil, :timestamp => nil, :time => nil, :date => nil, :binary => nil, :boolean => nil }\n\]\)\n\n\n$/)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should include timestamps if the TIMESTAMPS parameter is true' do
|
33
|
+
Rails.application.eager_load!
|
34
|
+
|
35
|
+
@env['MODELS'] = 'Sample'
|
36
|
+
@env['TIMESTAMPS'] = true
|
37
|
+
|
38
|
+
load_sample_data
|
39
|
+
|
40
|
+
@sd.setup @env
|
41
|
+
|
42
|
+
@sd.dump_models.should match(/^\nSample\.create!\(\[\n { :string => nil, :text => nil, :integer => nil, :float => nil, :decimal => nil, :datetime => nil, :timestamp => nil, :time => nil, :date => nil, :binary => nil, :boolean => nil, :created_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}", :updated_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}" }\n\]\)\n\n\n$/)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should include ids if the WITH_ID parameter is true' do
|
46
|
+
Rails.application.eager_load!
|
47
|
+
|
48
|
+
@env['MODELS'] = 'Sample'
|
49
|
+
@env['WITH_ID'] = true
|
50
|
+
|
51
|
+
@sd.setup @env
|
52
|
+
|
53
|
+
load_sample_data
|
54
|
+
|
55
|
+
@sd.dump_models.should match(/^\nSample\.create!\(\[\n { :id => \d+, :string => nil, :text => nil, :integer => nil, :float => nil, :decimal => nil, :datetime => nil, :timestamp => nil, :time => nil, :date => nil, :binary => nil, :boolean => nil, :created_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}", :updated_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}" }\n\]\)\n\n\n$/)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should respect the MODELS parameter' do
|
59
|
+
Rails.application.eager_load!
|
60
|
+
|
61
|
+
@env['MODELS'] = 'Sample'
|
62
|
+
|
63
|
+
@sd.setup @env
|
64
|
+
|
65
|
+
load_sample_data
|
66
|
+
|
67
|
+
@sd.dump_models.should match(/\nSample\.create!\(\[\n { :string => nil, :text => nil, :integer => nil, :float => nil, :decimal => nil, :datetime => nil, :timestamp => nil, :time => nil, :date => nil, :binary => nil, :boolean => nil, :created_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}", :updated_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}" }\n\]\)\n\n\n/)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should use the create method specified in the CREATE_METHOD parameter' do
|
71
|
+
load_sample_data
|
72
|
+
|
73
|
+
@env['MODELS'] = 'Sample'
|
74
|
+
@env['CREATE_METHOD'] = 'create'
|
75
|
+
|
76
|
+
@sd.setup @env
|
77
|
+
|
78
|
+
@sd.dump_models.should match(/\nSample\.create\(\[\n { :string => nil, :text => nil, :integer => nil, :float => nil, :decimal => nil, :datetime => nil, :timestamp => nil, :time => nil, :date => nil, :binary => nil, :boolean => nil, :created_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}", :updated_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}" }\n\]\)\n\n\n/)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should use 'create!' as the default create method" do
|
82
|
+
load_sample_data
|
83
|
+
|
84
|
+
@env['MODELS'] = 'Sample'
|
85
|
+
|
86
|
+
@sd.setup @env
|
87
|
+
|
88
|
+
@sd.dump_models.should match(/\nSample\.create!\(\[\n { :string => nil, :text => nil, :integer => nil, :float => nil, :decimal => nil, :datetime => nil, :timestamp => nil, :time => nil, :date => nil, :binary => nil, :boolean => nil, :created_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}", :updated_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}" }\n\]\)\n\n\n/)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return the contents of the dump" do
|
92
|
+
load_sample_data
|
93
|
+
|
94
|
+
@env['MODELS'] = 'Sample'
|
95
|
+
|
96
|
+
@sd.setup @env
|
97
|
+
|
98
|
+
@sd.dump_models.should match(/\nSample\.create!\(\[\n { :string => nil, :text => nil, :integer => nil, :float => nil, :decimal => nil, :datetime => nil, :timestamp => nil, :time => nil, :date => nil, :binary => nil, :boolean => nil, :created_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}", :updated_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}" }\n\]\)\n\n\n/)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should run ok without ActiveRecord::SchemaMigration being set (needed for Rails Engines)' do
|
102
|
+
schema_migration = ActiveRecord::SchemaMigration
|
103
|
+
|
104
|
+
ActiveRecord.send(:remove_const, :SchemaMigration)
|
105
|
+
|
106
|
+
begin
|
107
|
+
@sd.setup @env
|
108
|
+
|
109
|
+
@sd.dump_models
|
110
|
+
ensure
|
111
|
+
ActiveRecord.const_set(:SchemaMigration, schema_migration)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should skip any models whose tables don't exist" do
|
116
|
+
@sd.setup @env
|
117
|
+
|
118
|
+
load_sample_data
|
119
|
+
|
120
|
+
@sd.dump_models.should match(/\nSample\.create!\(\[\n { :string => nil, :text => nil, :integer => nil, :float => nil, :decimal => nil, :datetime => nil, :timestamp => nil, :time => nil, :date => nil, :binary => nil, :boolean => nil, :created_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}", :updated_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}" }\n\]\)\n\n\n/)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should skip any models that don't have have any rows" do
|
124
|
+
@sd.setup @env
|
125
|
+
|
126
|
+
@sd.dump_models.should_not include('EmptyModel')
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should respect the LIMIT parameter' do
|
130
|
+
load_sample_data
|
131
|
+
load_sample_data
|
132
|
+
|
133
|
+
@env['MODELS'] = 'Sample'
|
134
|
+
@env['LIMIT'] = '1'
|
135
|
+
|
136
|
+
@sd.setup @env
|
137
|
+
|
138
|
+
@sd.dump_models.should match(/\nSample\.create!\(\[\n { :string => nil, :text => nil, :integer => nil, :float => nil, :decimal => nil, :datetime => nil, :timestamp => nil, :time => nil, :date => nil, :binary => nil, :boolean => nil, :created_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}", :updated_at => "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}" }\n\]\)\n\n\n/)
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should only pull attributes that are returned as strings' do
|
142
|
+
load_sample_data
|
143
|
+
|
144
|
+
@env['MODELS'] = 'Sample'
|
145
|
+
@env['LIMIT'] = '1'
|
146
|
+
|
147
|
+
@sd.setup @env
|
148
|
+
|
149
|
+
original_attributes = Sample.new.attributes
|
150
|
+
attributes = original_attributes.merge(['col1', 'col2', 'col3'] => 'ABC')
|
151
|
+
|
152
|
+
Sample.any_instance.stub(:attributes).and_return(attributes)
|
153
|
+
|
154
|
+
@sd.dump_models.should eq("\nSample.create!([\n { :string => nil, :text => nil, :integer => nil, :float => nil, :decimal => nil, :datetime => nil, :timestamp => nil, :time => nil, :date => nil, :binary => nil, :boolean => nil, :created_at => nil, :updated_at => nil }\n])\n\n\n")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,30 @@
|
|
1
|
-
require 'seed_dump
|
1
|
+
require 'seed_dump'
|
2
2
|
require 'active_support/core_ext/string'
|
3
|
+
require 'active_support/descendants_tracker'
|
3
4
|
require 'active_record'
|
5
|
+
require 'byebug'
|
6
|
+
require 'database_cleaner'
|
7
|
+
require './spec/helpers'
|
8
|
+
|
9
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
4
10
|
|
5
11
|
RSpec.configure do |config|
|
6
12
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
7
|
-
config.run_all_when_everything_filtered = true
|
8
|
-
config.filter_run :focus
|
9
13
|
|
10
|
-
# Run specs in random order to surface order dependencies. If you find an
|
11
|
-
# order dependency and want to debug it, you can fix the order by providing
|
12
|
-
# the seed, which is printed after each run.
|
13
|
-
# --seed 1234
|
14
14
|
config.order = 'random'
|
15
|
+
|
16
|
+
config.include Helpers
|
17
|
+
|
18
|
+
config.before(:suite) do
|
19
|
+
DatabaseCleaner.strategy = :transaction
|
20
|
+
DatabaseCleaner.clean_with(:truncation)
|
21
|
+
end
|
22
|
+
|
23
|
+
config.before(:each) do
|
24
|
+
DatabaseCleaner.start
|
25
|
+
end
|
26
|
+
|
27
|
+
config.after(:each) do
|
28
|
+
DatabaseCleaner.clean
|
29
|
+
end
|
15
30
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seed_dump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Halff
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-10-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -39,6 +39,20 @@ dependencies:
|
|
39
39
|
- - '>='
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: byebug
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
57
|
name: jeweler
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,16 +84,13 @@ files:
|
|
70
84
|
- VERSION
|
71
85
|
- lib/clip.rb
|
72
86
|
- lib/seed_dump.rb
|
73
|
-
- lib/seed_dump/
|
87
|
+
- lib/seed_dump/dump_methods.rb
|
74
88
|
- lib/seed_dump/railtie.rb
|
75
89
|
- lib/tasks/seed_dump.rake
|
76
90
|
- lib/true.rb
|
77
91
|
- seed_dump.gemspec
|
78
|
-
- spec/
|
79
|
-
- spec/
|
80
|
-
- spec/models/nested/sample.rb
|
81
|
-
- spec/models/sample.rb
|
82
|
-
- spec/seed_dump_perform_spec.rb
|
92
|
+
- spec/helpers.rb
|
93
|
+
- spec/seed_dump_spec.rb
|
83
94
|
- spec/spec_helper.rb
|
84
95
|
homepage: https://github.com/rroblak/seed_dump
|
85
96
|
licenses: []
|
data/lib/seed_dump/perform.rb
DELETED
@@ -1,201 +0,0 @@
|
|
1
|
-
require "true"
|
2
|
-
require "clip"
|
3
|
-
|
4
|
-
module SeedDump
|
5
|
-
class Perform
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@opts = {}
|
9
|
-
@ar_options = {}
|
10
|
-
@indent = ""
|
11
|
-
@models = []
|
12
|
-
@last_record = []
|
13
|
-
@seed_rb = ""
|
14
|
-
@id_set_string = ""
|
15
|
-
@model_dir = 'app/models/**/*.rb'
|
16
|
-
end
|
17
|
-
|
18
|
-
def setup(env)
|
19
|
-
# config
|
20
|
-
@opts['verbose'] = env["VERBOSE"].true? || env['VERBOSE'].nil?
|
21
|
-
@opts['debug'] = env["DEBUG"].true?
|
22
|
-
@opts['with_id'] = env["WITH_ID"].true?
|
23
|
-
@opts['timestamps'] = env["TIMESTAMPS"].true? || env["TIMESTAMPS"].nil?
|
24
|
-
@opts['no-data'] = env['NO_DATA'].true?
|
25
|
-
@opts['skip_callbacks'] = env['SKIP_CALLBACKS'].true?
|
26
|
-
@opts['models'] = env['MODELS'] || (env['MODEL'] ? env['MODEL'] : "")
|
27
|
-
@opts['file'] = env['FILE'] || "#{Rails.root}/db/seeds.rb"
|
28
|
-
@opts['append'] = (env['APPEND'].true? && File.exists?(@opts['file']) )
|
29
|
-
@opts['max'] = env['MAX'] && env['MAX'].to_i > 0 ? env['MAX'].to_i : nil
|
30
|
-
@ar_options = env['LIMIT'].to_i > 0 ? { :limit => env['LIMIT'].to_i } : {}
|
31
|
-
@indent = " " * (env['INDENT'].nil? ? 2 : env['INDENT'].to_i)
|
32
|
-
@opts['models'] = @opts['models'].split(',').collect {|x| x.underscore.singularize.camelize }
|
33
|
-
@opts['schema'] = env['PG_SCHEMA']
|
34
|
-
@opts['model_dir'] = env['MODEL_DIR'] || @model_dir
|
35
|
-
@opts['create_method'] = env['CREATE_METHOD'] || 'create'
|
36
|
-
end
|
37
|
-
|
38
|
-
def log(msg)
|
39
|
-
puts msg if @opts['debug']
|
40
|
-
end
|
41
|
-
|
42
|
-
def load_models
|
43
|
-
log("Searching in #{@opts['model_dir']} for models")
|
44
|
-
|
45
|
-
Dir[File.join(Dir.pwd, @opts['model_dir'])].sort.each do |f|
|
46
|
-
log("Processing file #{f}")
|
47
|
-
|
48
|
-
dirname, basename = File.split(f)
|
49
|
-
|
50
|
-
dir_array = dirname.split(File::SEPARATOR)
|
51
|
-
|
52
|
-
# Find index of last occurence of 'models' in path
|
53
|
-
models_index = nil
|
54
|
-
dir_array.each_with_index {|x, i| models_index = i if x == 'models'}
|
55
|
-
|
56
|
-
model_dir_array = dir_array[models_index + 1..-1]
|
57
|
-
|
58
|
-
# Initialize nested model namespaces
|
59
|
-
model_dir_array.inject(Object) do |parent, child|
|
60
|
-
child = child.camelize
|
61
|
-
|
62
|
-
if parent.const_defined?(child)
|
63
|
-
parent.const_get(child)
|
64
|
-
else
|
65
|
-
parent.const_set(child, Module.new)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
require f
|
70
|
-
|
71
|
-
model = File.join(model_dir_array + [File.basename(basename, '.rb')]).camelize
|
72
|
-
|
73
|
-
log("Detected model #{model}")
|
74
|
-
|
75
|
-
@models << model if @opts['models'].include?(model) || @opts['models'].empty?
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def models
|
80
|
-
@models
|
81
|
-
end
|
82
|
-
|
83
|
-
def last_record
|
84
|
-
@last_record
|
85
|
-
end
|
86
|
-
|
87
|
-
def dump_attribute(a_s, r, k, v)
|
88
|
-
pushed = false
|
89
|
-
if v.is_a?(BigDecimal)
|
90
|
-
v = v.to_s
|
91
|
-
else
|
92
|
-
v = attribute_for_inspect(r,k)
|
93
|
-
end
|
94
|
-
|
95
|
-
unless k == 'id' && !@opts['with_id']
|
96
|
-
if (!(k == 'created_at' || k == 'updated_at') || @opts['timestamps'])
|
97
|
-
a_s.push("#{k.to_sym.inspect} => #{v}")
|
98
|
-
pushed = true
|
99
|
-
end
|
100
|
-
end
|
101
|
-
pushed
|
102
|
-
end
|
103
|
-
|
104
|
-
def dump_model(model)
|
105
|
-
@id_set_string = ''
|
106
|
-
@last_record = []
|
107
|
-
create_hash = ""
|
108
|
-
options = ''
|
109
|
-
rows = []
|
110
|
-
arr = nil
|
111
|
-
unless @opts['no-data']
|
112
|
-
arr = model.all
|
113
|
-
arr.limit(@ar_options[:limit]) if @ar_options[:limit]
|
114
|
-
end
|
115
|
-
arr = arr.empty? ? [model.new] : arr
|
116
|
-
|
117
|
-
arr.each_with_index { |r,i|
|
118
|
-
attr_s = [];
|
119
|
-
r.attributes.each do |k,v|
|
120
|
-
pushed_key = dump_attribute(attr_s,r,k,v)
|
121
|
-
@last_record.push k if pushed_key
|
122
|
-
end
|
123
|
-
rows.push "#{@indent}{ " << attr_s.join(', ') << " }"
|
124
|
-
}
|
125
|
-
|
126
|
-
if @opts['max']
|
127
|
-
splited_rows = rows.each_slice(@opts['max']).to_a
|
128
|
-
maxsarr = []
|
129
|
-
splited_rows.each do |sr|
|
130
|
-
maxsarr << "\n#{model}.#{@opts['create_method']}([\n" << sr.join(",\n") << "\n]#{options})\n"
|
131
|
-
end
|
132
|
-
maxsarr.join('')
|
133
|
-
else
|
134
|
-
"\n#{model}.#{@opts['create_method']}([\n" << rows.join(",\n") << "\n]#{options})\n"
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|
138
|
-
|
139
|
-
def dump_models
|
140
|
-
@seed_rb = ""
|
141
|
-
@models.sort.each do |model|
|
142
|
-
m = model.constantize
|
143
|
-
if m.ancestors.include?(ActiveRecord::Base) && !m.abstract_class
|
144
|
-
puts "Adding #{model} seeds." if @opts['verbose']
|
145
|
-
|
146
|
-
if @opts['skip_callbacks']
|
147
|
-
@seed_rb << "#{model}.reset_callbacks :save\n"
|
148
|
-
@seed_rb << "#{model}.reset_callbacks :create\n"
|
149
|
-
puts "Callbacks are disabled." if @opts['verbose']
|
150
|
-
end
|
151
|
-
|
152
|
-
@seed_rb << dump_model(m) << "\n\n"
|
153
|
-
else
|
154
|
-
puts "Skipping non-ActiveRecord model #{model}..." if @opts['verbose']
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
def write_file
|
160
|
-
File.open(@opts['file'], (@opts['append'] ? "a" : "w")) { |f|
|
161
|
-
f << "# encoding: utf-8\n"
|
162
|
-
f << "# Autogenerated by the db:seed:dump task\n# Do not hesitate to tweak this to your needs\n" unless @opts['append']
|
163
|
-
f << "#{@seed_rb}"
|
164
|
-
}
|
165
|
-
end
|
166
|
-
|
167
|
-
#override the rails version of this function to NOT truncate strings
|
168
|
-
def attribute_for_inspect(r,k)
|
169
|
-
value = r.attributes[k]
|
170
|
-
|
171
|
-
if value.is_a?(String) && value.length > 50
|
172
|
-
"#{value}".inspect
|
173
|
-
elsif value.is_a?(Date) || value.is_a?(Time)
|
174
|
-
%("#{value.to_s(:db)}")
|
175
|
-
else
|
176
|
-
value.inspect
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def set_search_path(path, append_public=true)
|
181
|
-
path_parts = [path.to_s, ('public' if append_public)].compact
|
182
|
-
ActiveRecord::Base.connection.schema_search_path = path_parts.join(',')
|
183
|
-
end
|
184
|
-
|
185
|
-
def run(env)
|
186
|
-
setup env
|
187
|
-
|
188
|
-
set_search_path @opts['schema'] if @opts['schema']
|
189
|
-
|
190
|
-
load_models
|
191
|
-
|
192
|
-
puts "Appending seeds to #{@opts['file']}." if @opts['append']
|
193
|
-
dump_models
|
194
|
-
|
195
|
-
puts "Writing #{@opts['file']}."
|
196
|
-
write_file
|
197
|
-
|
198
|
-
puts "Done."
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
data/spec/models/child_sample.rb
DELETED
data/spec/models/sample.rb
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe SeedDump::Perform do
|
4
|
-
before(:all) do
|
5
|
-
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
6
|
-
|
7
|
-
ActiveRecord::Schema.define(:version => 1) do
|
8
|
-
create_table 'child_samples', :force => true do |t|
|
9
|
-
t.string 'name'
|
10
|
-
t.datetime 'created_at', :null => false
|
11
|
-
t.datetime 'updated_at', :null => false
|
12
|
-
end
|
13
|
-
|
14
|
-
create_table 'samples', :force => true do |t|
|
15
|
-
t.string 'string'
|
16
|
-
t.text 'text'
|
17
|
-
t.integer 'integer'
|
18
|
-
t.float 'float'
|
19
|
-
t.decimal 'decimal'
|
20
|
-
t.datetime 'datetime'
|
21
|
-
t.datetime 'timestamp'
|
22
|
-
t.time 'time'
|
23
|
-
t.date 'date'
|
24
|
-
t.binary 'binary'
|
25
|
-
t.boolean 'boolean'
|
26
|
-
t.datetime 'created_at', :null => false
|
27
|
-
t.datetime 'updated_at', :null => false
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
before do
|
33
|
-
@sd = SeedDump::Perform.new
|
34
|
-
|
35
|
-
@env = {'MODEL_DIR' => 'spec/models/*.rb',
|
36
|
-
'FILE' => Dir.pwd + '/spec/db/seeds.rb',
|
37
|
-
'VERBOSE' => false,
|
38
|
-
'DEBUG' => false}
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'should load models from the specified directory' do
|
42
|
-
@sd.setup(@env)
|
43
|
-
|
44
|
-
@sd.load_models
|
45
|
-
|
46
|
-
@sd.models.should eq(["AbstractSample", "ChildSample", "Sample"])
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'should support nested models' do
|
50
|
-
@env['MODEL_DIR'] = 'spec/models/**/*.rb'
|
51
|
-
|
52
|
-
@sd.setup @env
|
53
|
-
|
54
|
-
@sd.load_models
|
55
|
-
|
56
|
-
@sd.models.should eq(['AbstractSample', 'ChildSample', 'Nested::Sample', 'Sample'])
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'should not include timestamps if the TIMESTAMPS parameter is false' do
|
60
|
-
@env['TIMESTAMPS'] = false
|
61
|
-
|
62
|
-
@sd.setup @env
|
63
|
-
|
64
|
-
@sd.load_models
|
65
|
-
|
66
|
-
@sd.dump_models
|
67
|
-
|
68
|
-
@sd.last_record.should_not include('created_at')
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'should include timestamps if the TIMESTAMPS parameter is true' do
|
72
|
-
@env['TIMESTAMPS'] = true
|
73
|
-
|
74
|
-
@sd.setup @env
|
75
|
-
|
76
|
-
@sd.load_models
|
77
|
-
|
78
|
-
@sd.dump_models
|
79
|
-
|
80
|
-
@sd.last_record.should include('created_at')
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'should include ids if the WITH_ID parameter is true' do
|
84
|
-
@env['WITH_ID'] = true
|
85
|
-
|
86
|
-
@sd.setup @env
|
87
|
-
|
88
|
-
@sd.load_models
|
89
|
-
|
90
|
-
@sd.dump_models
|
91
|
-
|
92
|
-
@sd.last_record.should include('id')
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'should skip abstract models' do
|
96
|
-
@env['MODELS'] = 'AbstractSample'
|
97
|
-
|
98
|
-
@sd.setup @env
|
99
|
-
|
100
|
-
@sd.load_models
|
101
|
-
|
102
|
-
@sd.dump_models
|
103
|
-
|
104
|
-
@sd.last_record.should eq([])
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'should use the create method specified in the CREATE_METHOD parameter' do
|
108
|
-
@env['CREATE_METHOD'] = 'create!'
|
109
|
-
|
110
|
-
@sd.setup @env
|
111
|
-
|
112
|
-
@sd.load_models
|
113
|
-
|
114
|
-
@sd.dump_models
|
115
|
-
|
116
|
-
@sd.instance_variable_get(:@seed_rb).should include('create!')
|
117
|
-
end
|
118
|
-
end
|