seed_dump 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|