seed-fu-discourse 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a80f7da73d20fcbc8d6388437e4581ec8b247b1e
4
+ data.tar.gz: beea3fef73d7dd503ee18e0713ef758767bed09e
5
+ SHA512:
6
+ metadata.gz: bc9b5fbb3f30e4426c2600858f93a1dd40f57aafd285d44ee22d5314eaf93929e863cbfd81df07f1424975ca1dd5b3d47d7323484ba52dd5b1b6a1745e19eba6
7
+ data.tar.gz: ab52d4e1cdf368d7d5efd73550e23cd05c48a72df61119a9b97dc40352a1104b147dfddf34aff0c4a6fb696d4156575d6510964361fb195cd7cf1ee62f0d51cc
data/CHANGELOG.md ADDED
@@ -0,0 +1,63 @@
1
+ Unreleased
2
+ ----------
3
+
4
+ Features:
5
+
6
+ * Rails 4.0.X support added. (by @tkhr, @DanielWright)
7
+
8
+ Version 2.1.0
9
+ -------------
10
+
11
+ Features:
12
+
13
+ * Deprecations removed
14
+
15
+ * Rails 3.1 support added, Rails 3.0 support removed (please use 2.0.X line with 3.0)
16
+
17
+ Version 2.0.1
18
+ -------------
19
+
20
+ Bug fixes:
21
+
22
+ * Update the primary key sequence in PostgreSQL tables after seeding data. This ensures that id conflicts do not occur when records are subsequently added to the table.
23
+
24
+ * Raise ActiveRecord::RecordNotSaved if any of the saves fail (but they won't fail due to validation since saves are done without validation, so this guards against callbacks failing etc.)
25
+
26
+ Version 2.0.0
27
+ -------------
28
+
29
+ Features:
30
+
31
+ * Depends only on Active Record, not the whole of Rails
32
+
33
+ * The `Model.seed_many` syntax is now supported by `Model.seed`, and `Model.seed_many` is deprecated
34
+
35
+ * `Model.seed` supports adding multiple records without an explicit array argument. I.e. the following are equivalent:
36
+
37
+ Model.seed([
38
+ { :name => "Jon" },
39
+ { :name => "Emily" }
40
+ ])
41
+
42
+ Model.seed(
43
+ { :name => "Jon" },
44
+ { :name => "Emily }
45
+ )
46
+
47
+ * A side-effect of the above is another option for single seeds:
48
+
49
+ Model.seed(:name => "Jon")
50
+
51
+ * The `SEED` option to `rake db:seed_fu` is deprecated, and replaced by `FILTER` which works the same way.
52
+
53
+ * Added `SeedFu.quiet` boolean option, set to `true` if you don't want any output from Seed Fu.
54
+
55
+ * Added `SeedFu.fixture_paths`. Set to an array of paths to look for seed files in. Defaults to `["db/fixtures"]` in general, or `["#{Rails.root}/db/fixtures", "#{Rails.root}/db/fixtures/#{Rails.env}"]` when Seed Fu is installed as a Rails plugin.
56
+
57
+ * Added `SeedFu.seed` method which is basically a method equivalent of running `rake db:seed_fu` (the rake task now just basically called `SeedFu.seed`)
58
+
59
+ * Simplified and changed the `SeedFu::Writer` API, see docs for details
60
+
61
+ Bug fixes:
62
+
63
+ * Fix Rails 3 deprecation warnings and make seed-fu fully compatible with being installed as a gem
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2010 Michael Bleigh
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,158 @@
1
+ Seed Fu
2
+ =======
3
+
4
+ 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.
5
+
6
+ Warning: API Changes
7
+ --------------------
8
+
9
+ Version 2.0.0 of Seed Fu introduced API changes. `Seed::Writer` was been completely overhauled and will require you to update your scripts. Some other deprecations were introduced, and support is fully removed in version 2.1.0. Please see the [CHANGELOG](CHANGELOG.md) for details.
10
+
11
+ The API documentation is available in full at [http://rubydoc.info/github/mbleigh/seed-fu/master/frames](http://rubydoc.info/github/mbleigh/seed-fu/master/frames).
12
+
13
+ Basic Example
14
+ -------------
15
+
16
+ ### In `db/fixtures/users.rb`
17
+
18
+ User.seed do |s|
19
+ s.id = 1
20
+ s.login = "jon"
21
+ s.email = "jon@example.com"
22
+ s.name = "Jon"
23
+ end
24
+
25
+ User.seed do |s|
26
+ s.id = 2
27
+ s.login = "emily"
28
+ s.email = "emily@example.com"
29
+ s.name = "Emily"
30
+ end
31
+
32
+ ### To load the data:
33
+
34
+ $ rake db:seed_fu
35
+ == Seed from /path/to/app/db/fixtures/users.rb
36
+ - User {:id=>1, :login=>"jon", :email=>"jon@example.com", :name=>"Jon"}
37
+ - User {:id=>2, :login=>"emily", :email=>"emily@example.com", :name=>"Emily"}
38
+
39
+ Installation
40
+ ------------
41
+
42
+ ### Rails 4.0
43
+
44
+ The current latest version isn't compatible with Rails 4.0.
45
+ You will have to use the HEAD of this repo.
46
+
47
+ gem 'seed-fu', github: 'mbleigh/seed-fu'
48
+
49
+ ### Rails 3.1
50
+
51
+ Just add `gem 'seed-fu', '~> 2.1.0'` to your `Gemfile`
52
+
53
+ Seed Fu depends on Active Record, but doesn't have to be used with a full Rails app. Simply load and require the `seed-fu` gem and you're set.
54
+
55
+ ### Rails 3.0
56
+
57
+ The current version is not backwards compatible with Rails 3.0. Please use `gem 'seed-fu', '~> 2.0.0'`.
58
+
59
+ ### Rails 2.3
60
+
61
+ The current version is not backwards compatible with Rails 2.3. Please use `gem 'seed-fu', '~> 1.2.0'`.
62
+
63
+ Constraints
64
+ -----------
65
+
66
+ Constraints are used to identify seeds, so that they can be updated if necessary. For example:
67
+
68
+ Point.seed(:x, :y) do |s|
69
+ s.x = 4
70
+ s.y = 7
71
+ s.name = "Home"
72
+ end
73
+
74
+ The first time this seed is loaded, a `Point` record will be created. Now suppose the name is changed:
75
+
76
+ Point.seed(:x, :y) do |s|
77
+ s.x = 4
78
+ s.y = 7
79
+ s.name = "Work"
80
+ end
81
+
82
+ When this is run, Seed Fu will look for a `Point` based on the `:x` and `:y` constraints provided. It will see that a matching `Point` already exists and so update its attributes rather than create a new record.
83
+
84
+ If you do not want seeds to be updated after they have been created, use `seed_once`:
85
+
86
+ Point.seed_once(:x, :y) do |s|
87
+ s.x = 4
88
+ s.y = 7
89
+ s.name = "Home"
90
+ end
91
+
92
+ The default constraint just checks the `id` of the record.
93
+
94
+ Where to put seed files
95
+ -----------------------
96
+
97
+ By default, seed files are looked for in the following locations:
98
+
99
+ * `Rails.root/db/fixtures` and `Rails.root/db/fixtures/Rails.env` in a Rails app
100
+ * `db/fixtures` when loaded without Rails
101
+
102
+ You can change these defaults by modifying the `SeedFu.fixture_paths` array.
103
+
104
+ Seed files can be named whatever you like, and are loaded in alphabetical order.
105
+
106
+ Terser syntax
107
+ -------------
108
+
109
+ When loading lots of records, the above block-based syntax can be quite verbose. You can use the following instead:
110
+
111
+ User.seed(:id,
112
+ { :id => 1, :login => "jon", :email => "jon@example.com", :name => "Jon" },
113
+ { :id => 2, :login => "emily", :email => "emily@example.com", :name => "Emily" }
114
+ )
115
+
116
+ Rake task
117
+ ---------
118
+
119
+ Seed files can be run automatically using `rake db:seed_fu`. There are two options which you can pass:
120
+
121
+ * `rake db:seed_fu FIXTURE_PATH=path/to/fixtures` -- Where to find the fixtures
122
+ * `rake db:seed_fu FILTER=users,articles` -- Only run seed files with a filename matching the `FILTER`
123
+
124
+ You can also do a similar thing in your code by calling `SeedFu.seed(fixture_paths, filter)`.
125
+
126
+ Disable output
127
+ --------------
128
+
129
+ To disable output from Seed Fu, set `SeedFu.quiet = true`.
130
+
131
+ Handling large seed files
132
+ -------------------------
133
+
134
+ Seed files can be huge. To handle large files (over a million rows), try these tricks:
135
+
136
+ * Gzip your fixtures. Seed Fu will read .rb.gz files happily. `gzip -9` gives the best compression, and with Seed Fu's repetitive syntax, a 160M file can shrink to 16M.
137
+ * Add lines reading `# BREAK EVAL` 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.
138
+ * Load a single fixture at a time with the `FILTER` environment variable
139
+ * If you don't need Seed Fu's ability to update seed with new data, then you may find that [activerecord-import](https://github.com/zdennis/activerecord-import) is faster
140
+
141
+ Generating seed files
142
+ ---------------------
143
+
144
+ If you need to programmatically generate seed files, for example to convert a CSV file into a seed file, then you can use [`SeedFu::Writer`](../SeedFu/Writer).
145
+
146
+ Bugs / Feature requests
147
+ -----------------------
148
+
149
+ Please report them on [Github Issues](https://github.com/mbleigh/seed-fu/issues).
150
+
151
+ Contributors
152
+ ------------
153
+
154
+ * [Michael Bleigh](http://www.mbleigh.com/) is the original author
155
+ * [Jon Leighton](http://jonathanleighton.com/) is the current maintainer
156
+ * Thanks to [Matthew Beale](https://github.com/mixonic) for his great work in adding the writer, making it faster and better.
157
+
158
+ Copyright © 2008-2010 Michael Bleigh, released under the MIT license
data/lib/seed-fu.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'active_record'
2
+ require 'active_support/core_ext/module/attribute_accessors'
3
+ require 'seed-fu/railtie' if defined?(Rails) && Rails.version >= "3"
4
+
5
+ module SeedFu
6
+ autoload :VERSION, 'seed-fu/version'
7
+ autoload :Seeder, 'seed-fu/seeder'
8
+ autoload :ActiveRecordExtension, 'seed-fu/active_record_extension'
9
+ autoload :BlockHash, 'seed-fu/block_hash'
10
+ autoload :Runner, 'seed-fu/runner'
11
+ autoload :Writer, 'seed-fu/writer'
12
+
13
+ mattr_accessor :quiet
14
+
15
+ # Set `SeedFu.quiet = true` to silence all output
16
+ @@quiet = false
17
+
18
+ mattr_accessor :fixture_paths
19
+
20
+ # Set this to be an array of paths to directories containing your seed files. If used as a Rails
21
+ # plugin, SeedFu will set to to contain `Rails.root/db/fixtures` and
22
+ # `Rails.root/db/fixtures/Rails.env`
23
+ @@fixture_paths = ['db/fixtures']
24
+
25
+ # Load seed data from files
26
+ # @param [Array] fixture_paths The paths to look for seed files in
27
+ # @param [Regexp] filter If given, only filenames matching this expression will be loaded
28
+ def self.seed(fixture_paths = SeedFu.fixture_paths, filter = nil)
29
+ Runner.new(fixture_paths, filter).run
30
+ end
31
+ end
32
+
33
+ # @public
34
+ class ActiveRecord::Base
35
+ extend SeedFu::ActiveRecordExtension
36
+ end
@@ -0,0 +1,65 @@
1
+ module SeedFu
2
+ module ActiveRecordExtension
3
+ # Load some seed data. There are two ways to do this.
4
+ #
5
+ # Verbose syntax
6
+ # --------------
7
+ #
8
+ # This will seed a single record. The `:id` parameter ensures that if a record already exists
9
+ # in the database with the same id, then it will be updated with the name and age, rather
10
+ # than created from scratch.
11
+ #
12
+ # Person.seed(:id) do |s|
13
+ # s.id = 1
14
+ # s.name = "Jon"
15
+ # s.age = 21
16
+ # end
17
+ #
18
+ # Note that `:id` is the default attribute used to identify a seed, so it need not be
19
+ # specified.
20
+ #
21
+ # Terse syntax
22
+ # ------------
23
+ #
24
+ # This is a more succinct way to load multiple records. Note that both `:x` and `:y` are being
25
+ # used to identify a seed here.
26
+ #
27
+ # Point.seed(:x, :y,
28
+ # { :x => 3, :y => 10, :name => "Home" },
29
+ # { :x => 5, :y => 9, :name => "Office" }
30
+ # )
31
+ def seed(*args, &block)
32
+ SeedFu::Seeder.new(self, *parse_seed_fu_args(args, block)).seed
33
+ end
34
+
35
+ # Has the same syntax as {#seed}, but if a record already exists with the same values for
36
+ # constraining attributes, it will not be updated.
37
+ #
38
+ # @example
39
+ # Person.seed(:id, :id => 1, :name => "Jon") # => Record created
40
+ # Person.seed(:id, :id => 1, :name => "Bob") # => Name changed
41
+ # Person.seed(:id, :id => 1, :name => "Harry") # => Name *not* changed
42
+ def seed_once(*args, &block)
43
+ constraints, data = parse_seed_fu_args(args, block)
44
+ SeedFu::Seeder.new(self, constraints, data, :insert_only => true).seed
45
+ end
46
+
47
+ private
48
+
49
+ def parse_seed_fu_args(args, block)
50
+ if block.nil?
51
+ if args.last.is_a?(Array)
52
+ # Last arg is an array of data, so assume the rest of the args are constraints
53
+ data = args.pop
54
+ [args, data]
55
+ else
56
+ # Partition the args, assuming the first hash is the start of the data
57
+ args.partition { |arg| !arg.is_a?(Hash) }
58
+ end
59
+ else
60
+ # We have a block, so assume the args are all constraints
61
+ [args, [SeedFu::BlockHash.new(block).to_hash]]
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,21 @@
1
+ module SeedFu
2
+ # @private
3
+ class BlockHash
4
+ def initialize(proc)
5
+ @hash = {}
6
+ proc.call(self)
7
+ end
8
+
9
+ def to_hash
10
+ @hash
11
+ end
12
+
13
+ def method_missing(method_name, *args, &block)
14
+ if method_name.to_s =~ /^(.*)=$/ && args.length == 1 && block.nil?
15
+ @hash[$1] = args.first
16
+ else
17
+ super
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ module SeedFu
2
+ class Railtie < Rails::Railtie
3
+ rake_tasks do
4
+ load "tasks/seed_fu.rake"
5
+ end
6
+
7
+ initializer 'seed_fu.set_fixture_paths' do
8
+ SeedFu.fixture_paths = [
9
+ Rails.root.join('db/fixtures').to_s,
10
+ Rails.root.join('db/fixtures/' + Rails.env).to_s
11
+ ]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,73 @@
1
+ require 'zlib'
2
+ require 'active_support/core_ext/array/wrap'
3
+
4
+ module SeedFu
5
+ # Runs seed files.
6
+ #
7
+ # It is not recommended to use this class directly. Instead, use {SeedFu.seed SeedFu.seed}, which creates
8
+ # an instead of {Runner} and calls {#run #run}.
9
+ #
10
+ # @see SeedFu.seed SeedFu.seed
11
+ class Runner
12
+ # @param [Array<String>] fixture_paths The paths where fixtures are located. Will use
13
+ # `SeedFu.fixture_paths` if {nil}. If the argument is not an array, it will be wrapped by one.
14
+ # @param [Regexp] filter If given, only seed files with a file name matching this pattern will
15
+ # be used
16
+ def initialize(fixture_paths = nil, filter = nil)
17
+ @fixture_paths = Array.wrap(fixture_paths || SeedFu.fixture_paths)
18
+ @filter = filter
19
+ end
20
+
21
+ # Run the seed files.
22
+ def run
23
+ puts "\n== Filtering seed files against regexp: #{@filter.inspect}" if @filter && !SeedFu.quiet
24
+
25
+ filenames.each do |filename|
26
+ run_file(filename)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def run_file(filename)
33
+ puts "\n== Seed from #{filename}" unless SeedFu.quiet
34
+
35
+ ActiveRecord::Base.transaction do
36
+ open(filename) do |file|
37
+ chunked_ruby = ''
38
+ file.each_line do |line|
39
+ if line == "# BREAK EVAL\n"
40
+ eval(chunked_ruby)
41
+ chunked_ruby = ''
42
+ else
43
+ chunked_ruby << line
44
+ end
45
+ end
46
+ eval(chunked_ruby) unless chunked_ruby == ''
47
+ end
48
+ end
49
+ end
50
+
51
+ def open(filename)
52
+ if filename[-3..-1] == '.gz'
53
+ Zlib::GzipReader.open(filename) do |file|
54
+ yield file
55
+ end
56
+ else
57
+ File.open(filename) do |file|
58
+ yield file
59
+ end
60
+ end
61
+ end
62
+
63
+ def filenames
64
+ filenames = []
65
+ @fixture_paths.each do |path|
66
+ filenames += (Dir[File.join(path, '*.rb')] + Dir[File.join(path, '*.rb.gz')]).sort
67
+ end
68
+ filenames.uniq!
69
+ filenames = filenames.find_all { |filename| filename =~ @filter } if @filter
70
+ filenames
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,104 @@
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
+ records = @model_class.transaction do
36
+ @data.map { |record_data| seed_record(record_data.symbolize_keys) }
37
+ end
38
+ update_id_sequence
39
+ records
40
+ end
41
+
42
+ private
43
+
44
+ def validate_constraints!
45
+ unknown_columns = @constraints.map(&:to_s) - @model_class.column_names
46
+ unless unknown_columns.empty?
47
+ raise(ArgumentError,
48
+ "Your seed constraints contained unknown columns: #{column_list(unknown_columns)}. " +
49
+ "Valid columns are: #{column_list(@model_class.column_names)}.")
50
+ end
51
+ end
52
+
53
+ def validate_data!
54
+ raise ArgumentError, "Seed data missing" if @data.empty?
55
+ end
56
+
57
+ def column_list(columns)
58
+ '`' + columns.join("`, `") + '`'
59
+ end
60
+
61
+ def seed_record(data)
62
+ record = find_or_initialize_record(data)
63
+ return if @options[:insert_only] && !record.new_record?
64
+
65
+ puts " - #{@model_class} #{data.inspect}" unless @options[:quiet]
66
+
67
+ # Rails 3 or Rails 4 + rails/protected_attributes
68
+ if record.class.respond_to?(:protected_attributes) && record.class.respond_to?(:accessible_attributes)
69
+ record.assign_attributes(data, :without_protection => true)
70
+ # Rails 4 without rails/protected_attributes
71
+ else
72
+ record.assign_attributes(data)
73
+ end
74
+ record.save(:validate => false) || raise(ActiveRecord::RecordNotSaved)
75
+ record
76
+ end
77
+
78
+ def find_or_initialize_record(data)
79
+ @model_class.where(constraint_conditions(data)).first ||
80
+ @model_class.new
81
+ end
82
+
83
+ def constraint_conditions(data)
84
+ Hash[@constraints.map { |c| [c, data[c.to_sym]] }]
85
+ end
86
+
87
+ def update_id_sequence
88
+ if @model_class.connection.adapter_name == "PostgreSQL"
89
+ quoted_sequence = "'" + @model_class.sequence_name + "'"
90
+ next_id = (@model_class.maximum(:id) || 0) + 1
91
+
92
+ # nothing to repair, the id sequence starts at 1
93
+ if(next_id > 1)
94
+ @model_class.connection.execute(
95
+ "SELECT pg_catalog.setval(" +
96
+ "#{quoted_sequence}," +
97
+ " #{next_id}" +
98
+ ");"
99
+ )
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,4 @@
1
+ module SeedFu
2
+ # The current version of Seed Fu
3
+ VERSION = '2.2.0'
4
+ end
@@ -0,0 +1,132 @@
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.add(:first_name => 'Jon', :last_name => 'Smith', :age => 21)
9
+ # writer.add(: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,38 @@
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["FILTER"]
29
+ filter = /#{ENV["FILTER"].gsub(/,/, "|")}/
30
+ end
31
+
32
+ if ENV["FIXTURE_PATH"]
33
+ fixture_paths = [ENV["FIXTURE_PATH"], ENV["FIXTURE_PATH"] + '/' + Rails.env]
34
+ end
35
+
36
+ SeedFu.seed(fixture_paths, filter)
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: seed-fu-discourse
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Bleigh
8
+ - Jon Leighton
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-12-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '3.1'
21
+ - - <
22
+ - !ruby/object:Gem::Version
23
+ version: '4.1'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '3.1'
31
+ - - <
32
+ - !ruby/object:Gem::Version
33
+ version: '4.1'
34
+ - !ruby/object:Gem::Dependency
35
+ name: activesupport
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '3.1'
41
+ - - <
42
+ - !ruby/object:Gem::Version
43
+ version: '4.1'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '3.1'
51
+ - - <
52
+ - !ruby/object:Gem::Version
53
+ version: '4.1'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rspec
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ version: '2.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: '2.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: pg
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: mysql2
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: sqlite3
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Seed Fu is an attempt to once and for all solve the problem of inserting
111
+ and maintaining seed data in a database. It uses a variety of techniques gathered
112
+ from various places around the web and combines them to create what is hopefully
113
+ the most robust seed data system around.
114
+ email:
115
+ - michael@intridea.com
116
+ - j@jonathanleighton.com
117
+ executables: []
118
+ extensions: []
119
+ extra_rdoc_files: []
120
+ files:
121
+ - lib/seed-fu.rb
122
+ - lib/tasks/seed_fu.rake
123
+ - lib/seed-fu/railtie.rb
124
+ - lib/seed-fu/writer.rb
125
+ - lib/seed-fu/runner.rb
126
+ - lib/seed-fu/block_hash.rb
127
+ - lib/seed-fu/seeder.rb
128
+ - lib/seed-fu/active_record_extension.rb
129
+ - lib/seed-fu/version.rb
130
+ - LICENSE
131
+ - README.md
132
+ - CHANGELOG.md
133
+ homepage: http://github.com/mbleigh/seed-fu
134
+ licenses: []
135
+ metadata: {}
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.0.14
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: Easily manage seed data in your Active Record application
156
+ test_files: []