Froze rails gems
[depot.git] / vendor / rails / railties / doc / guides / source / creating_plugins / migration_generator.txt
1 == Create a generator ==
2
3 Many plugins ship with generators. When you created the plugin above, you specified the --with-generator option, so you already have the generator stubs in 'vendor/plugins/yaffle/generators/yaffle'.
4
5 Building generators is a complex topic unto itself and this section will cover one small aspect of generators: creating a generator that adds a time-stamped migration.
6
7 To create a generator you must:
8
9 * Add your instructions to the 'manifest' method of the generator
10 * Add any necessary template files to the templates directory
11 * Test the generator manually by running various combinations of `script/generate` and `script/destroy`
12 * Update the USAGE file to add helpful documentation for your generator
13
14 === Testing generators ===
15
16 Many rails plugin authors do not test their generators, however testing generators is quite simple. A typical generator test does the following:
17
18 * Creates a new fake rails root directory that will serve as destination
19 * Runs the generator forward and backward, making whatever assertions are necessary
20 * Removes the fake rails root
21
22 For the generator in this section, the test could look something like this:
23
24 *vendor/plugins/yaffle/test/yaffle_generator_test.rb*
25
26 [source, ruby]
27 ------------------------------------------------------------------
28 require File.dirname(__FILE__) + '/test_helper.rb'
29 require 'rails_generator'
30 require 'rails_generator/scripts/generate'
31 require 'rails_generator/scripts/destroy'
32
33 class GeneratorTest < Test::Unit::TestCase
34
35 def fake_rails_root
36 File.join(File.dirname(__FILE__), 'rails_root')
37 end
38
39 def file_list
40 Dir.glob(File.join(fake_rails_root, "db", "migrate", "*"))
41 end
42
43 def setup
44 FileUtils.mkdir_p(fake_rails_root)
45 @original_files = file_list
46 end
47
48 def teardown
49 FileUtils.rm_r(fake_rails_root)
50 end
51
52 def test_generates_correct_file_name
53 Rails::Generator::Scripts::Generate.new.run(["yaffle", "bird"], :destination => fake_rails_root)
54 new_file = (file_list - @original_files).first
55 assert_match /add_yaffle_fields_to_bird/, new_file
56 end
57
58 end
59 ------------------------------------------------------------------
60
61 You can run 'rake' from the plugin directory to see this fail. Unless you are doing more advanced generator commands it typically suffices to just test the Generate script, and trust that rails will handle the Destroy and Update commands for you.
62
63 === Adding to the manifest ===
64
65 This example will demonstrate how to use one of the built-in generator methods named 'migration_template' to create a migration file. To start, update your generator file to look like this:
66
67 *vendor/plugins/yaffle/generators/yaffle/yaffle_generator.rb*
68
69 [source, ruby]
70 ------------------------------------------------------------------
71 class YaffleGenerator < Rails::Generator::NamedBase
72 def manifest
73 record do |m|
74 m.migration_template 'migration:migration.rb', "db/migrate", {:assigns => yaffle_local_assigns,
75 :migration_file_name => "add_yaffle_fields_to_#{custom_file_name}"
76 }
77 end
78 end
79
80 private
81 def custom_file_name
82 custom_name = class_name.underscore.downcase
83 custom_name = custom_name.pluralize if ActiveRecord::Base.pluralize_table_names
84 end
85
86 def yaffle_local_assigns
87 returning(assigns = {}) do
88 assigns[:migration_action] = "add"
89 assigns[:class_name] = "add_yaffle_fields_to_#{custom_file_name}"
90 assigns[:table_name] = custom_file_name
91 assigns[:attributes] = [Rails::Generator::GeneratedAttribute.new("last_squawk", "string")]
92 end
93 end
94 end
95 ------------------------------------------------------------------
96
97 The generator creates a new file in 'db/migrate' with a timestamp and an 'add_column' statement. It reuses the built in rails `migration_template` method, and reuses the built-in rails migration template.
98
99 It's courteous to check to see if table names are being pluralized whenever you create a generator that needs to be aware of table names. This way people using your generator won't have to manually change the generated files if they've turned pluralization off.
100
101 === Manually test the generator ===
102
103 To run the generator, type the following at the command line:
104
105 ------------------------------------------------------------------
106 ./script/generate yaffle bird
107 ------------------------------------------------------------------
108
109 and you will see a new file:
110
111 *db/migrate/20080529225649_add_yaffle_fields_to_birds.rb*
112
113 [source, ruby]
114 ------------------------------------------------------------------
115 class AddYaffleFieldsToBirds < ActiveRecord::Migration
116 def self.up
117 add_column :birds, :last_squawk, :string
118 end
119
120 def self.down
121 remove_column :birds, :last_squawk
122 end
123 end
124 ------------------------------------------------------------------
125
126
127 === The USAGE file ===
128
129 Rails ships with several built-in generators. You can see all of the generators available to you by typing the following at the command line:
130
131 ------------------------------------------------------------------
132 script/generate
133 ------------------------------------------------------------------
134
135 You should see something like this:
136
137 ------------------------------------------------------------------
138 Installed Generators
139 Plugins (vendor/plugins): yaffle
140 Builtin: controller, integration_test, mailer, migration, model, observer, plugin, resource, scaffold, session_migration
141 ------------------------------------------------------------------
142
143 When you run `script/generate yaffle` you should see the contents of your 'vendor/plugins/yaffle/generators/yaffle/USAGE' file.
144
145 For this plugin, update the USAGE file looks like this:
146
147 ------------------------------------------------------------------
148 Description:
149 Creates a migration that adds yaffle squawk fields to the given model
150
151 Example:
152 ./script/generate yaffle hickwall
153
154 This will create:
155 db/migrate/TIMESTAMP_add_yaffle_fields_to_hickwall
156 ------------------------------------------------------------------