railties 3.0.0.beta4 → 3.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/CHANGELOG +24 -6
  2. data/README.rdoc +25 -0
  3. data/guides/assets/javascripts/code_highlighter.js +0 -0
  4. data/guides/assets/javascripts/guides.js +0 -0
  5. data/guides/assets/stylesheets/print.css +0 -0
  6. data/guides/assets/stylesheets/reset.css +0 -0
  7. data/guides/assets/stylesheets/style.css +0 -0
  8. data/guides/source/3_0_release_notes.textile +5 -3
  9. data/guides/source/action_controller_overview.textile +19 -0
  10. data/guides/source/active_record_basics.textile +27 -21
  11. data/guides/source/active_record_querying.textile +39 -37
  12. data/guides/source/{activerecord_validations_callbacks.textile → active_record_validations_callbacks.textile} +30 -29
  13. data/guides/source/active_support_core_extensions.textile +232 -107
  14. data/guides/source/api_documentation_guidelines.textile +187 -0
  15. data/guides/source/association_basics.textile +45 -1
  16. data/guides/source/configuring.textile +7 -7
  17. data/guides/source/contributing_to_rails.textile +42 -15
  18. data/guides/source/form_helpers.textile +1 -1
  19. data/guides/source/generators.textile +37 -37
  20. data/guides/source/getting_started.textile +11 -11
  21. data/guides/source/i18n.textile +1 -1
  22. data/guides/source/index.html.erb +14 -6
  23. data/guides/source/initialization.textile +130 -124
  24. data/guides/source/layout.html.erb +5 -2
  25. data/guides/source/layouts_and_rendering.textile +2 -2
  26. data/guides/source/migrations.textile +4 -3
  27. data/guides/source/plugins.textile +15 -15
  28. data/guides/source/rails_application_templates.textile +2 -2
  29. data/guides/source/routing.textile +83 -62
  30. data/guides/source/security.textile +2 -2
  31. data/guides/w3c_validator.rb +30 -6
  32. data/lib/rails.rb +3 -3
  33. data/lib/rails/application.rb +43 -19
  34. data/lib/rails/application/bootstrap.rb +2 -0
  35. data/lib/rails/application/configuration.rb +3 -3
  36. data/lib/rails/application/finisher.rb +6 -6
  37. data/lib/rails/cli.rb +1 -19
  38. data/lib/rails/commands.rb +5 -5
  39. data/lib/rails/commands/application.rb +1 -1
  40. data/lib/rails/commands/console.rb +1 -4
  41. data/lib/rails/commands/generate.rb +0 -0
  42. data/lib/rails/commands/plugin.rb +57 -52
  43. data/lib/rails/commands/runner.rb +2 -1
  44. data/lib/rails/commands/server.rb +6 -2
  45. data/lib/rails/configuration.rb +2 -3
  46. data/lib/rails/console/app.rb +0 -2
  47. data/lib/rails/engine.rb +14 -15
  48. data/lib/rails/engine/configuration.rb +5 -5
  49. data/lib/rails/generators.rb +2 -3
  50. data/lib/rails/generators/actions.rb +4 -4
  51. data/lib/rails/generators/base.rb +1 -1
  52. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +1 -6
  53. data/lib/rails/generators/erb/scaffold/templates/_form.html.erb +4 -4
  54. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb +3 -3
  55. data/lib/rails/generators/erb/scaffold/templates/index.html.erb +7 -7
  56. data/lib/rails/generators/erb/scaffold/templates/new.html.erb +2 -2
  57. data/lib/rails/generators/erb/scaffold/templates/show.html.erb +3 -3
  58. data/lib/rails/generators/generated_attribute.rb +2 -1
  59. data/lib/rails/generators/named_base.rb +24 -0
  60. data/lib/rails/generators/rails/app/app_generator.rb +10 -9
  61. data/lib/rails/generators/rails/app/templates/Gemfile +4 -3
  62. data/lib/rails/generators/rails/app/templates/README +6 -31
  63. data/lib/rails/generators/rails/app/templates/Rakefile +1 -1
  64. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb +0 -1
  65. data/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +0 -0
  66. data/lib/rails/generators/rails/app/templates/config/application.rb +11 -11
  67. data/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml +36 -24
  68. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +1 -1
  69. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +1 -1
  70. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +3 -0
  71. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +3 -0
  72. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +3 -0
  73. data/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb +1 -1
  74. data/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt +2 -2
  75. data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +2 -2
  76. data/lib/rails/generators/rails/app/templates/config/routes.rb +1 -1
  77. data/lib/rails/generators/rails/app/templates/public/index.html +0 -17
  78. data/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js +2027 -900
  79. data/lib/rails/generators/rails/app/templates/public/javascripts/rails.js +114 -57
  80. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +1 -1
  81. data/lib/rails/generators/rails/model/USAGE +1 -1
  82. data/lib/rails/generators/rails/resource/resource_generator.rb +4 -14
  83. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +0 -2
  84. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +28 -30
  85. data/lib/rails/generators/resource_helpers.rb +1 -1
  86. data/lib/rails/generators/test_case.rb +25 -11
  87. data/lib/rails/generators/test_unit/model/model_generator.rb +1 -1
  88. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +0 -1
  89. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +13 -15
  90. data/lib/rails/info.rb +1 -2
  91. data/lib/rails/info_routes.rb +1 -1
  92. data/lib/rails/initializable.rb +3 -16
  93. data/lib/rails/paths.rb +31 -36
  94. data/lib/rails/plugin.rb +10 -6
  95. data/lib/rails/rack/logger.rb +11 -13
  96. data/lib/rails/railtie.rb +14 -42
  97. data/lib/rails/ruby_version_check.rb +19 -5
  98. data/lib/rails/script_rails_loader.rb +29 -0
  99. data/lib/rails/tasks/annotations.rake +2 -2
  100. data/lib/rails/tasks/documentation.rake +47 -16
  101. data/lib/rails/tasks/framework.rake +9 -9
  102. data/lib/rails/tasks/middleware.rake +1 -1
  103. data/lib/rails/tasks/misc.rake +5 -5
  104. data/lib/rails/tasks/routes.rake +1 -1
  105. data/lib/rails/tasks/tmp.rake +5 -5
  106. data/lib/rails/test_unit/testing.rake +38 -14
  107. data/lib/rails/version.rb +1 -1
  108. metadata +29 -17
  109. data/README +0 -281
  110. data/lib/rails/application/routes_reloader.rb +0 -46
  111. data/lib/rails/log_subscriber.rb +0 -115
  112. data/lib/rails/log_subscriber/test_helper.rb +0 -97
  113. data/lib/rails/webrick_server.rb +0 -156
@@ -0,0 +1,187 @@
1
+ h2. API Documentation Guidelines
2
+
3
+ This guide documents the Ruby on Rails API documentation guidelines.
4
+
5
+ endprologue.
6
+
7
+ h3. RDoc
8
+
9
+ The Rails API documentation is generated with RDoc 2.5. Please consult the "RDoc documentation":http://rdoc.rubyforge.org/RDoc.htmlFor for help with its markup.
10
+
11
+ h3. Wording
12
+
13
+ Write simple, declarative sentences. Brevity is a plus: get to the point.
14
+
15
+ Write in present tense: "Returns a hash that...", rather than "Returned a hash that..." or "Will return a hash that...".
16
+
17
+ Start comments in upper case, follow regular punctuation rules:
18
+
19
+ <ruby>
20
+ # Declares an attribute reader backed by an internally-named instance variable.
21
+ def attr_internal_reader(*attrs)
22
+ ...
23
+ end
24
+ </ruby>
25
+
26
+ Communicate to the reader the current way of doing things, both explicitly and implicitly. Use the recommended idioms in edge, reorder sections to emphasize favored approaches if needed, etc. The documentation should be a model for best practices and canonical, modern Rails usage.
27
+
28
+ Documentation has to be concise but comprehensive. Explore and document edge cases. What happens if a module is anonymous? What if a collection is empty? What if an argument is nil?
29
+
30
+ The proper names of Rails components have a space in between the words, like "Active Support". +ActiveRecord+ is a Ruby module, whereas Active Record is an ORM. Historically there has been lack of consistency regarding this, but we checked with David when docrails started. All Rails documentation consistently refer to Rails components by their proper name, and if in your next blog post or presentation you remember this tidbit and take it into account that'd be fenomenal :).
31
+
32
+ Spell names correctly: HTML, MySQL, JavaScript, ERb.
33
+
34
+ h3. Example Code
35
+
36
+ Choose meaningful examples that depict and cover the basics as well as interesting points or gotchas.
37
+
38
+ Use two spaces to indent chunks of code.—that is two spaces with respect to the left margin; the examples
39
+ themselves should use "Rails code conventions":http://rails.lighthouseapp.com/projects/8994/source-style.
40
+
41
+ Short docs do not need an explicit "Examples" label to introduce snippets, they just follow paragraphs:
42
+
43
+ <ruby>
44
+ # Converts a collection of elements into a formatted string by calling
45
+ # <tt>to_s</tt> on all elements and joining them.
46
+ #
47
+ # Blog.find(:all).to_formatted_s # => "First PostSecond PostThird Post"
48
+ </ruby>
49
+
50
+ On the other hand big chunks of structured documentation may have a separate "Examples" section:
51
+
52
+ <ruby>
53
+ # ==== Examples
54
+ #
55
+ # Person.exists?(5)
56
+ # Person.exists?('5')
57
+ # Person.exists?(:name => "David")
58
+ # Person.exists?(['name LIKE ?', "%#{query}%"])
59
+ </ruby>
60
+
61
+ The result of expressions follow them and are introduced by "# => ", vertically aligned:
62
+
63
+ <ruby>
64
+ # For checking if a fixnum is even or odd.
65
+ #
66
+ # 1.even? # => false
67
+ # 1.odd? # => true
68
+ # 2.even? # => true
69
+ # 2.odd? # => false
70
+ </ruby>
71
+
72
+ If a line is too long, the comment may be placed on the next line:
73
+
74
+ <ruby>
75
+ # label(:post, :title)
76
+ # # => <label for="post_title">Title</label>
77
+ #
78
+ # label(:post, :title, "A short title")
79
+ # # => <label for="post_title">A short title</label>
80
+ #
81
+ # label(:post, :title, "A short title", :class => "title_label")
82
+ # # => <label for="post_title" class="title_label">A short title</label>
83
+ </ruby>
84
+
85
+ Avoid using any printing methods like +puts+ or +p+ for that purpose.
86
+
87
+ On the other hand, regular comments do not use an arrow:
88
+
89
+ <ruby>
90
+ # polymorphic_url(record) # same as comment_url(record)
91
+ </ruby>
92
+
93
+ h3. Filenames
94
+
95
+ As a rule of thumb use filenames relative to the application root:
96
+
97
+ <plain>
98
+ config/routes.rb # YES
99
+ routes.rb # NO
100
+ RAILS_ROOT/config/routes.rb # NO
101
+ </plain>
102
+
103
+
104
+ h3. Fonts
105
+
106
+ h4. Fixed-width Font
107
+
108
+ Use fixed-width fonts for:
109
+ * constants, in particular class and module names
110
+ * method names
111
+ * literals like +nil+, +false+, +true+, +self+
112
+ * symbols
113
+ * method parameters
114
+ * file names
115
+
116
+ <ruby>
117
+ # Copies the instance variables of +object+ into +self+.
118
+ #
119
+ # Instance variable names in the +exclude+ array are ignored. If +object+
120
+ # responds to <tt>protected_instance_variables</tt> the ones returned are
121
+ # also ignored. For example, Rails controllers implement that method.
122
+ # ...
123
+ def copy_instance_variables_from(object, exclude = [])
124
+ ...
125
+ end
126
+ </ruby>
127
+
128
+ WARNING: Using a pair of +&#43;...&#43;+ for fixed-width font only works with *words*; that is: anything matching <tt>\A\w&#43;\z</tt>. For anything else use +&lt;tt&gt;...&lt;/tt&gt;+, notably symbols, setters, inline snippets, etc:
129
+
130
+ h4. Regular Font
131
+
132
+ When "true" and "false" are English words rather than Ruby keywords use a regular font:
133
+
134
+ <ruby>
135
+ # If <tt>reload_plugins?</tt> is false, add this to your plugin's <tt>init.rb</tt>
136
+ # to make it reloadable:
137
+ #
138
+ # Dependencies.load_once_paths.delete lib_path
139
+ </ruby>
140
+
141
+ h3. Description Lists
142
+
143
+ In lists of options, parameters, etc. use a hyphen between the item and its description (reads better than a colon because normally options are symbols):
144
+
145
+ <ruby>
146
+ # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
147
+ </ruby>
148
+
149
+ The description starts in upper case and ends with a full stop—it's standard English.
150
+
151
+ h3. Dynamically Generated Methods
152
+
153
+ Methods created with +(module|class)_eval(STRING)+ have a comment by their side with an instance of the generated code. That comment is 2 spaces apart from the template:
154
+
155
+ <ruby>
156
+ for severity in Severity.constants
157
+ class_eval <<-EOT, __FILE__, __LINE__
158
+ def #{severity.downcase}(message = nil, progname = nil, &block) # def debug(message = nil, progname = nil, &block)
159
+ add(#{severity}, message, progname, &block) # add(DEBUG, message, progname, &block)
160
+ end # end
161
+ #
162
+ def #{severity.downcase}? # def debug?
163
+ #{severity} >= @level # DEBUG >= @level
164
+ end # end
165
+ EOT
166
+ end
167
+ </ruby>
168
+
169
+ If the resulting lines are too wide, say 200 columns or more, we put the comment above the call:
170
+
171
+ <ruby>
172
+ # def self.find_by_login_and_activated(*args)
173
+ # options = args.extract_options!
174
+ # ...
175
+ # end
176
+ self.class_eval %{
177
+ def self.#{method_id}(*args)
178
+ options = args.extract_options!
179
+ ...
180
+ end
181
+ }
182
+ </ruby>
183
+
184
+ h3. Changelog
185
+
186
+ * July 17, 2010: ported from the docrails wiki and revised by "Xavier Noria":credits.html#fxn
187
+
@@ -137,6 +137,16 @@ end
137
137
 
138
138
  !images/has_many_through.png(has_many :through Association Diagram)!
139
139
 
140
+ The collection of join models can be managed via the API. For example, if you assign
141
+
142
+ <ruby>
143
+ physician.patients = patients
144
+ </ruby>
145
+
146
+ new join models are created for newly associated objects, and if some are gone their rows are deleted.
147
+
148
+ WARNING: Automatic deletion of join models is direct, no destroy callbacks are triggered.
149
+
140
150
  The +has_many :through+ association is also useful for setting up "shortcuts" through nested +has_many+ associations. For example, if a document has many sections, and a section has many paragraphs, you may sometimes want to get a simple collection of all paragraphs in the document. You could set that up this way:
141
151
 
142
152
  <ruby>
@@ -1361,7 +1371,41 @@ The +:through+ option specifies a join model through which to perform the query.
1361
1371
 
1362
1372
  h6(#has_many-uniq). +:uniq+
1363
1373
 
1364
- Specify the +:uniq => true+ option to remove duplicates from the collection. This is most useful in conjunction with the +:through+ option.
1374
+ Set the +:uniq+ option to true to keep the collection free of duplicates. This is mostly useful together with the +:through+ option.
1375
+
1376
+ <ruby>
1377
+ class Person < ActiveRecord::Base
1378
+ has_many :readings
1379
+ has_many :posts, :through => :readings
1380
+ end
1381
+
1382
+ person = Person.create(:name => 'john')
1383
+ post = Post.create(:name => 'a1')
1384
+ person.posts << post
1385
+ person.posts << post
1386
+ person.posts.inspect # => [#<Post id: 5, name: "a1">, #<Post id: 5, name: "a1">]
1387
+ Reading.all.inspect # => [#<Reading id: 12, person_id: 5, post_id: 5>, #<Reading id: 13, person_id: 5, post_id: 5>]
1388
+ </ruby>
1389
+
1390
+ In the above case there are two readings and +person.posts+ brings out both of them even though these records are pointing to the same post.
1391
+
1392
+ Now let's set +:uniq+ to true:
1393
+
1394
+ <ruby>
1395
+ class Person
1396
+ has_many :readings
1397
+ has_many :posts, :through => :readings, :uniq => true
1398
+ end
1399
+
1400
+ person = Person.create(:name => 'honda')
1401
+ post = Post.create(:name => 'a1')
1402
+ person.posts << post
1403
+ person.posts << post
1404
+ person.posts.inspect # => [#<Post id: 7, name: "a1">]
1405
+ Reading.all.inspect # => [#<Reading id: 16, person_id: 7, post_id: 7>, #<Reading id: 17, person_id: 7, post_id: 7>]
1406
+ </ruby>
1407
+
1408
+ In the above case there are still two readings. However +person.posts+ shows only one post because the collection loads only unique records.
1365
1409
 
1366
1410
  h6(#has_many-validate). +:validate+
1367
1411
 
@@ -135,7 +135,7 @@ h4. Configuring Action Controller
135
135
 
136
136
  * +config.action_controller.allow_concurrency+ should be set to +true+ to allow concurrent (threadsafe) action processing. Set to +false+ by default. You probably don't want to call this one directly, though, because a series of other adjustments need to be made for threadsafe mode to work properly. Instead, you should simply call +config.threadsafe!+ inside your +production.rb+ file, which makes all the necessary adjustments.
137
137
 
138
- WARNING: Threadsafe operation in incompatible with the normal workings of development mode Rails. In particular, automatic dependency loading and class reloading are automatically disabled when you call +config.threadsafe!+.
138
+ WARNING: Threadsafe operation is incompatible with the normal workings of development mode Rails. In particular, automatic dependency loading and class reloading are automatically disabled when you call +config.threadsafe!+.
139
139
 
140
140
  * +config.action_controller.param_parsers+ provides an array of handlers that can extract information from incoming HTTP requests and add it to the +params+ hash. By default, parsers for multipart forms, URL-encoded forms, XML, and JSON are active.
141
141
 
@@ -167,9 +167,9 @@ The caching code adds two additional settings:
167
167
 
168
168
  The Active Record session store can also be configured:
169
169
 
170
- * +ActiveRecord::SessionStore::Session.table_name+ sets the name of the table uses to store sessions. Defaults to +sessions+.
170
+ * +ActiveRecord::SessionStore::Session.table_name+ sets the name of the table used to store sessions. Defaults to +sessions+.
171
171
 
172
- * +ActiveRecord::SessionStore::Session.primary_key+ sets the name of the ID column uses in the sessions table. Defaults to +session_id+.
172
+ * +ActiveRecord::SessionStore::Session.primary_key+ sets the name of the ID column used in the sessions table. Defaults to +session_id+.
173
173
 
174
174
  * +ActiveRecord::SessionStore::Session.data_column_name+ sets the name of the column which stores marshaled session data. Defaults to +data+.
175
175
 
@@ -181,7 +181,7 @@ There are only a few configuration options for Action View, starting with four o
181
181
 
182
182
  * +config.action_view.warn_cache_misses+ tells Rails to display a warning whenever an action results in a cache miss on your view paths. The default is +false+.
183
183
 
184
- * +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| "&lt;div class=\"fieldWithErrors\"&gt;#{html_tag}&lt;/div&gt;" }</tt>
184
+ * +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| "&lt;div class=\"field_with_errors\"&gt;#{html_tag}&lt;/div&gt;" }</tt>
185
185
 
186
186
  * +config.action_view.default_form_builder+ tells Rails which form builder to use by default. The default is +ActionView::Helpers::FormBuilder+.
187
187
 
@@ -235,9 +235,9 @@ h4. Configuring Active Support
235
235
 
236
236
  There are a few configuration options available in Active Support:
237
237
 
238
- * +config.active_support.escape_html_entities_in_json+ enables or disables the escaping of HTML entities in JSON serialization. Defaults to _true_.
238
+ * +config.active_support.escape_html_entities_in_json+ enables or disables the escaping of HTML entities in JSON serialization. Defaults to +true+.
239
239
 
240
- * +config.active_support.use_standard_json_time_format+ enables or disables serializing dates to ISO 8601 format. Defaults to _false_.
240
+ * +config.active_support.use_standard_json_time_format+ enables or disables serializing dates to ISO 8601 format. Defaults to +false+.
241
241
 
242
242
  * +ActiveSupport::BufferedLogger.silencer+ is set to +false+ to disable the ability to silence logging in a block. The default is +true+.
243
243
 
@@ -247,7 +247,7 @@ There are a few configuration options available in Active Support:
247
247
 
248
248
  h3. Using Initializers
249
249
 
250
- After it loads the framework plus any gems and plugins in your application, Rails turns to loading initializers. An initializer is any file of ruby code stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks and plugins are loaded.
250
+ After loading the framework and any gems and plugins in your application, Rails turns to loading initializers. An initializer is any file of Ruby code stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks and plugins are loaded.
251
251
 
252
252
  NOTE: You can use subfolders to organize your initializers if you like, because Rails will look into the whole file hierarchy from the +initializers+ folder on down.
253
253
 
@@ -62,26 +62,39 @@ git clone git://github.com/rails/rails.git
62
62
  cd rails
63
63
  </shell>
64
64
 
65
- h4. Pick a Branch
65
+ h4. Set up and Run the Tests
66
66
 
67
- Currently, there is active work being done on both the 2-3-stable branch of Rails and on the master branch (which will become Rails 3.0). If you want to work with the master branch, you're all set. To work with 2.3, you'll need to set up and switch to your own local tracking branch:
67
+ All of the Rails tests must pass with any code you submit, otherwise you have no chance of getting code accepted. This means you need to be able to run the tests. First, you need to install all Rails dependencies with bundler:
68
68
 
69
69
  <shell>
70
- git branch --track 2-3-stable origin/2-3-stable
71
- git checkout 2-3-stable
70
+ gem install bundler
71
+ bundle install --without db
72
72
  </shell>
73
73
 
74
- TIP: You may want to "put your git branch name in your shell prompt":http://github.com/guides/put-your-git-branch-name-in-your-shell-prompt to make it easier to remember which version of the code you're working with.
74
+ The second command will install all dependencies, except MySQL and PostgreSQL. We will come back at these soon. With dependencies installed, you can run the whole Rails test suite with:
75
75
 
76
- h4. Set up and Run the Tests
76
+ <shell>
77
+ rake test
78
+ </shell>
77
79
 
78
- All of the Rails tests must pass with any code you submit, otherwise you have no chance of getting code accepted. This means you need to be able to run the tests. Rails needs the +mocha+ gem for running some tests, so install it with:
80
+ You can also run tests for an specific framework, like Action Pack, by going into its directory and executing the same command:
79
81
 
80
82
  <shell>
81
- gem install mocha
83
+ cd actionpack
84
+ rake test
82
85
  </shell>
83
86
 
84
- For the tests that touch the database, this means creating test databases. If you're using MySQL, create a user named +rails+ with privileges on the test databases.
87
+ h4. Testing Active Record
88
+
89
+ By default, when you run Active Record tests, it will execute the test suite three times, one for each of the main databases: SQLite3, MySQL and PostgreSQL. If you are adding a feature that is not specific to the database, you can run the test suite (or just one file) for just one of them. Here is an example for SQLite3:
90
+
91
+ <shell>
92
+ cd activerecord
93
+ rake test_sqlite3
94
+ rake test_sqlite3 TEST=test/cases/validations_test.rb
95
+ </shell>
96
+
97
+ If you want to use another database, as MySQL, you need to create a user named +rails+ with privileges on the test databases.
85
98
 
86
99
  <shell>
87
100
  mysql> GRANT ALL PRIVILEGES ON activerecord_unittest.*
@@ -90,7 +103,13 @@ mysql> GRANT ALL PRIVILEGES ON activerecord_unittest2.*
90
103
  to 'rails'@'localhost';
91
104
  </shell>
92
105
 
93
- Enter this from the +activerecord+ directory to create the test databases:
106
+ Then ensure you run bundle install without the +--without db+ option:
107
+
108
+ <shell>
109
+ bundle install
110
+ </shell>
111
+
112
+ Finally, enter this from the +activerecord+ directory to create the test databases:
94
113
 
95
114
  <shell>
96
115
  rake mysql:build_databases
@@ -100,18 +119,26 @@ NOTE: Using the rake task to create the test databases ensures they have the cor
100
119
 
101
120
  If you’re using another database, check the files under +activerecord/test/connections+ in the Rails source code for default connection information. You can edit these files if you _must_ on your machine to provide different credentials, but obviously you should not push any such changes back to Rails.
102
121
 
103
- Now if you go back to the root of the Rails source on your machine and run +rake+ with no parameters, you should see every test in all of the Rails components pass. If you want to run the all ActiveRecord tests (or just a single one) with another database adapter, enter this from the +activerecord+ directory:
122
+ You can now run tests as you did for +sqlite3+:
104
123
 
105
124
  <shell>
106
- rake test_sqlite3
107
- rake test_sqlite3 TEST=test/cases/validations_test.rb
125
+ rake test_mysql
108
126
  </shell>
109
127
 
110
- You can replace +sqlite3+ with +jdbcmysql+, +jdbcsqlite3+, +jdbcpostgresql+, +mysql+ or +postgresql+. Check out the file +activerecord/RUNNING_UNIT_TESTS+ for information on running more targeted database tests, or the file +ci/ci_build.rb+ to see the test suite that the Rails continuous integration server runs.
128
+ You can also +myqsl+ with +postgresql+, +jdbcmysql+, +jdbcsqlite3+ or +jdbcpostgresql+. Check out the file +activerecord/RUNNING_UNIT_TESTS+ for information on running more targeted database tests, or the file +ci/ci_build.rb+ to see the test suite that the Rails continuous integration server runs.
111
129
 
130
+ NOTE: If you're working with Active Record code, you _must_ ensure that the tests pass for at least MySQL, PostgreSQL, and SQLite 3. Subtle differences between the various Active Record database adapters have been behind the rejection of many patches that looked OK when tested only against MySQL.
112
131
 
132
+ h4. Older versions of Rails
113
133
 
114
- NOTE: If you're working with Active Record code, you _must_ ensure that the tests pass for at least MySQL, PostgreSQL, and SQLite 3. Subtle differences between the various Active Record database adapters have been behind the rejection of many patches that looked OK when tested only against MySQL.
134
+ If you want to work add a fix to older versions of Rails, you'll need to set up and switch to your own local tracking branch. Here is an example to switch to Rails 2.3 branch:
135
+
136
+ <shell>
137
+ git branch --track 2-3-stable origin/2-3-stable
138
+ git checkout 2-3-stable
139
+ </shell>
140
+
141
+ TIP: You may want to "put your git branch name in your shell prompt":http://github.com/guides/put-your-git-branch-name-in-your-shell-prompt to make it easier to remember which version of the code you're working with.
115
142
 
116
143
  h3. Helping to Resolve Existing Issues
117
144
 
@@ -205,7 +205,7 @@ Upon form submission the value entered by the user will be stored in +params[:pe
205
205
 
206
206
  WARNING: You must pass the name of an instance variable, i.e. +:person+ or +"person"+, not an actual instance of your model object.
207
207
 
208
- Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the "Active Record Validations and Callbacks":./activerecord_validations_callbacks.html#displaying-validation-errors-in-the-view guide.
208
+ Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the "Active Record Validations and Callbacks":./active_record_validations_callbacks.html#displaying-validation-errors-in-the-view guide.
209
209
 
210
210
  h4. Binding a Form to an Object
211
211
 
@@ -1,21 +1,21 @@
1
- h2. Creating and customizing Rails Generators
1
+ h2. Creating and Customizing Rails Generators
2
2
 
3
3
  Rails generators are an essential tool if you plan to improve your workflow and in this guide you will learn how to create and customize already existing generators.
4
4
 
5
5
  In this guide you will:
6
6
 
7
- * Learn how to see which generators are available in your application;
8
- * Create a generator using templates;
9
- * Learn how Rails searches for generators before invoking them;
10
- * Customize your scaffold by creating new generators;
11
- * Customize your scaffold by changing generators templates;
12
- * Learn how to use fallbacks to avoid overwriting a huge set of generators;
7
+ * Learn how to see which generators are available in your application
8
+ * Create a generator using templates
9
+ * Learn how Rails searches for generators before invoking them
10
+ * Customize your scaffold by creating new generators
11
+ * Customize your scaffold by changing generator templates
12
+ * Learn how to use fallbacks to avoid overwriting a huge set of generators
13
13
 
14
14
  endprologue.
15
15
 
16
16
  NOTE: This guide is about Rails generators for versions >= 3.0. Rails generators from previous versions are not supported.
17
17
 
18
- h3. First contact
18
+ h3. First Contact
19
19
 
20
20
  When you create an application using the +rails+ command, you are in fact using a Rails generator. After that, you can get a list of all available generators by just invoking +rails generate+:
21
21
 
@@ -25,15 +25,15 @@ $ cd myapp
25
25
  $ rails generate
26
26
  </shell>
27
27
 
28
- You will get a list of all generators that comes with Rails. If you need a detailed description, for instance about the helper generator, you can simply do:
28
+ You will get a list of all generators that comes with Rails. If you need a detailed description of the helper generator, for example, you can simply do:
29
29
 
30
30
  <shell>
31
31
  $ rails generate helper --help
32
32
  </shell>
33
33
 
34
- h3. Creating your first generator
34
+ h3. Creating Your First Generator
35
35
 
36
- Since Rails 3.0, generators are built on top of "Thor":http://github.com/wycats/thor. Thor has a powerful options parsing and a great API for manipulating files. For instance, let's build a generator that creates an initializer file named +initializer.rb+ inside +config/initializers+.
36
+ Since Rails 3.0, generators are built on top of "Thor":http://github.com/wycats/thor. Thor provides powerful options parsing and a great API for manipulating files. For instance, let's build a generator that creates an initializer file named +initializer.rb+ inside +config/initializers+.
37
37
 
38
38
  The first step is to create a file at +RAILS_APP/lib/generators/initializer_generator.rb+ with the following content:
39
39
 
@@ -45,7 +45,7 @@ class InitializerGenerator < Rails::Generators::Base
45
45
  end
46
46
  </ruby>
47
47
 
48
- Our new generator is quite simple: it inherits from +Rails::Generators::Base+ and have one method definition. Each public method in the generator is executed when a generator is invoked. Finally, we invoke the +create_file+ method that will create a file at the given destination with the given content. If you are familiar with Rails Application Templates API, you are at home with new generators API.
48
+ Our new generator is quite simple: it inherits from +Rails::Generators::Base+ and has one method definition. Each public method in the generator is executed when a generator is invoked. Finally, we invoke the +create_file+ method that will create a file at the given destination with the given content. If you are familiar with the Rails Application Templates API, you'll feel right at home with the new generators API.
49
49
 
50
50
  To invoke our new generator, we just need to do:
51
51
 
@@ -59,7 +59,7 @@ Before we go on, let's see our brand new generator description:
59
59
  $ rails generate initializer --help
60
60
  </shell>
61
61
 
62
- Rails usually is able to generate good descriptions if a generator is namespaced, as +ActiveRecord::Generators::ModelGenerator+, but not in this particular case. We can solve this problem in two ways. The first one is calling +desc+ inside our generator:
62
+ Rails is usually able to generate good descriptions if a generator is namespaced, as +ActiveRecord::Generators::ModelGenerator+, but not in this particular case. We can solve this problem in two ways. The first one is calling +desc+ inside our generator:
63
63
 
64
64
  <ruby>
65
65
  class InitializerGenerator < Rails::Generators::Base
@@ -70,9 +70,9 @@ class InitializerGenerator < Rails::Generators::Base
70
70
  end
71
71
  </ruby>
72
72
 
73
- Now we can see the new description by invoking +--help+ in the new generator. The second way to add a description is by creating a file named +USAGE+ in the same directory as our generator. We are going to do that in the next step.
73
+ Now we can see the new description by invoking +--help+ on the new generator. The second way to add a description is by creating a file named +USAGE+ in the same directory as our generator. We are going to do that in the next step.
74
74
 
75
- h3. Creating generators with generators
75
+ h3. Creating Generators with Generators
76
76
 
77
77
  A faster way to create a generator is using the generator's generator:
78
78
 
@@ -84,7 +84,7 @@ $ rails generate generator initializer
84
84
  create lib/generators/initializer/templates
85
85
  </shell>
86
86
 
87
- And it will create a new generator as follow:
87
+ And it will create a new generator as follows:
88
88
 
89
89
  <ruby>
90
90
  class InitializerGenerator < Rails::Generators::NamedBase
@@ -92,7 +92,7 @@ class InitializerGenerator < Rails::Generators::NamedBase
92
92
  end
93
93
  </ruby>
94
94
 
95
- At first, we can notice that we are inheriting from +Rails::Generators::NamedBase+ instead of +Rails::Generators::Base+. This means that our generator expects as least one argument, which will be the name of the initializer.
95
+ First, notice that we are inheriting from +Rails::Generators::NamedBase+ instead of +Rails::Generators::Base+. This means that our generator expects as least one argument, which will be the name of the initializer.
96
96
 
97
97
  We can see that by invoking the description of this new generator (don't forget to delete the old generator file):
98
98
 
@@ -127,13 +127,13 @@ And let's execute our generator:
127
127
  $ rails generate initializer foo
128
128
  </shell>
129
129
 
130
- We can see that now a initializer named foo was created at +config/initializers/foo.rb+ with the contents of our template. That means that copy_file copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+.
130
+ We can see that now a initializer named foo was created at +config/initializers/foo.rb+ with the contents of our template. That means that +copy_file+ copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+.
131
131
 
132
- h3. Generators lookup
132
+ h3. Generators Lookup
133
133
 
134
- With our first generator created, we must discuss briefly generators lookup. The way Rails finds generators is exactly the same way Ruby find files, i.e. using +$LOAD_PATHS+.
134
+ Now that we've created our first generator, we need to briefly discuss generator lookup. The way Rails finds generators is exactly the same way Ruby find files, i.e. using +$LOAD_PATHS+.
135
135
 
136
- For instance, when you say +rails g initializer foo+, rails knows you want to invoke the initializer generator and then search for the following generators in the $LOAD_PATHS:
136
+ For instance, when you say +rails generate initializer foo+, Rails knows you want to invoke the initializer generator and then search for the following generators in the $LOAD_PATHS:
137
137
 
138
138
  <shell>
139
139
  rails/generators/initializer/initializer_generator.rb
@@ -144,7 +144,7 @@ generators/initializer_generator.rb
144
144
 
145
145
  If none of them is found, it raises an error message.
146
146
 
147
- h3. Customizing your workflow
147
+ h3. Customizing Your Workflow
148
148
 
149
149
  Rails generators are flexible enough to let you customize your scaffold the way you want. In your +config/application.rb+ there is a section just for generators:
150
150
 
@@ -156,7 +156,7 @@ config.generators do |g|
156
156
  end
157
157
  </ruby>
158
158
 
159
- Before we customize our workflow, let's first see how our scaffold looks like:
159
+ Before we customize our workflow, let's first see what our scaffold looks like:
160
160
 
161
161
  <shell>
162
162
  $ rails generate scaffold User name:string
@@ -186,7 +186,7 @@ $ rails generate scaffold User name:string
186
186
  create public/stylesheets/scaffold.css
187
187
  </shell>
188
188
 
189
- Looking at this output, is easy to understand how generators work on Rails 3.0 and above. The scaffold generator actually doesn't generate anything, it just invokes others to do the work. This allows us to add/replace/remove any of those invocations. For instance, the scaffold generator invokes the scaffold_controller generator, which invokes erb, test_unit and helper generators. Since each generator has a single responsibility, they are easy to reuse, avoiding code duplication.
189
+ Looking at this output, it's easy to understand how generators work on Rails 3.0 and above. The scaffold generator doesn't actually generate anything, it just invokes others to do the work. This allows us to add/replace/remove any of those invocations. For instance, the scaffold generator invokes the scaffold_controller generator, which invokes erb, test_unit and helper generators. Since each generator has a single responsibility, they are easy to reuse, avoiding code duplication.
190
190
 
191
191
  Our first customization on the workflow will be to stop generating stylesheets and test fixtures on scaffold. We can achieve that by changing our application to the following:
192
192
 
@@ -199,15 +199,15 @@ config.generators do |g|
199
199
  end
200
200
  </ruby>
201
201
 
202
- If we generate another resource on scaffold, we can notice that neither stylesheets nor fixtures are created anymore. If you want to customize it further, for example to use +Datamapper+ and +Rspec+ instead of +ActiveRecord+ and +TestUnit+, is just a matter of adding their gems to your application and configuring your generators.
202
+ If we generate another resource on scaffold, we can notice that neither stylesheets nor fixtures are created anymore. If you want to customize it further, for example to use +Datamapper+ and +RSpec+ instead of +ActiveRecord+ and +TestUnit+, it's just a matter of adding their gems to your application and configuring your generators.
203
203
 
204
- To show that, we are going to create a new helper generator that simply adds some instance variable readers. First, we create a generator:
204
+ To demonstrate this, we are going to create a new helper generator that simply adds some instance variable readers. First, we create a generator:
205
205
 
206
206
  <shell>
207
207
  $ rails generate generator my_helper
208
208
  </shell>
209
209
 
210
- After that, we can delete both templates directory and the +source_root+ class method from our new generators, because we are not going to need them. So our new generator looks like the following:
210
+ After that, we can delete both the +templates+ directory and the +source_root+ class method from our new generators, because we are not going to need them. So our new generator looks like the following:
211
211
 
212
212
  <ruby>
213
213
  class MyHelperGenerator < Rails::Generators::NamedBase
@@ -227,7 +227,7 @@ We can try out our new generator by creating a helper for users:
227
227
  $ rails generate my_helper users
228
228
  </shell>
229
229
 
230
- And it will generate the following helper file in app/helpers:
230
+ And it will generate the following helper file in +app/helpers+:
231
231
 
232
232
  <ruby>
233
233
  module UsersHelper
@@ -258,7 +258,7 @@ $ rails generate scaffold Post body:text
258
258
 
259
259
  We can notice on the output that our new helper was invoked instead of the Rails default. However one thing is missing, which is tests for our new generator and to do that, we are going to reuse old helpers test generators.
260
260
 
261
- Since Rails 3.0, this is easy to do due to the hooks concept. Our new helper does not need to be focused in one specific test framework, it can simply provide a hook and a test framework just need to implement this hook in order to be compatible.
261
+ Since Rails 3.0, this is easy to do due to the hooks concept. Our new helper does not need to be focused in one specific test framework, it can simply provide a hook and a test framework just needs to implement this hook in order to be compatible.
262
262
 
263
263
  To do that, we can change your generator to the following:
264
264
 
@@ -276,7 +276,7 @@ end
276
276
  end
277
277
  </ruby>
278
278
 
279
- Now, when the helper generator is invoked and let's say test unit is configured as test framework, it will try to invoke both +MyHelper::Generators::TestUnitGenerator+ and +TestUnit::Generators::MyHelperGenerator+. Since none of those are defined, we can tell our generator to invoke +TestUnit::Generators::HelperGenerator+ instead, which is defined since it's a Rails generator. To do that, we just need to add:
279
+ Now, when the helper generator is invoked and TestUnit is configured as the test framework, it will try to invoke both +MyHelper::Generators::TestUnitGenerator+ and +TestUnit::Generators::MyHelperGenerator+. Since none of those are defined, we can tell our generator to invoke +TestUnit::Generators::HelperGenerator+ instead, which is defined since it's a Rails generator. To do that, we just need to add:
280
280
 
281
281
  <ruby>
282
282
  # Search for :helper instead of :my_helper
@@ -285,11 +285,11 @@ Now, when the helper generator is invoked and let's say test unit is configured
285
285
 
286
286
  And now you can re-run scaffold for another resource and see it generating tests as well!
287
287
 
288
- h3. Customizing your workflow by changing generators templates
288
+ h3. Customizing Your Workflow by Changing Generators Templates
289
289
 
290
290
  In the step above, we simply wanted to add a line to the generated helper, without adding any extra functionality. There is a simpler way to do that, and it's by replacing the templates of already existing generators.
291
291
 
292
- In Rails 3.0 and above, generators does not look only in the source root for templates, they also search for templates in other paths. And one of them is inside +RAILS_APP/lib/templates+. Since we want to customize +Rails::Generators::HelperGenerator+, we can do that by simple making a template copy inside +RAILS_APP/lib/templates/rails/helper+ with the name +helper.rb+. So let's create such file with the following content:
292
+ In Rails 3.0 and above, generators don't just look in the source root for templates, they also search for templates in other paths. And one of them is inside +RAILS_APP/lib/templates+. Since we want to customize +Rails::Generators::HelperGenerator+, we can do that by simply making a template copy inside +RAILS_APP/lib/templates/rails/helper+ with the name +helper.rb+. So let's create that file with the following content:
293
293
 
294
294
  <erb>
295
295
  module <%= class_name %>Helper
@@ -310,9 +310,9 @@ end
310
310
 
311
311
  If you generate another resource, you can see that we got exactly the same result! This is useful if you want to customize your scaffold templates and/or layout by just creating +edit.html.erb+, +index.html.erb+ and so on inside +RAILS_APP/lib/templates/erb/scaffold+.
312
312
 
313
- h3. Adding generators fallbacks
313
+ h3. Adding Generators Fallbacks
314
314
 
315
- One last feature about generators which is quite useful for plugin generators is fallbacks. For example, imagine that you want to add a feature on top of TestUnit test framework, like "shoulda":http://github.com/thoughtbot/shoulda does. Since TestUnit already implements all generators required by Rails and shoulda just want to overwrite part of it, there is no need for shoulda to reimplement some generators again, they can simply tell Rails to use a +TestUnit+ generator if none was found under +Shoulda+ namespace.
315
+ One last feature about generators which is quite useful for plugin generators is fallbacks. For example, imagine that you want to add a feature on top of TestUnit test framework, like "shoulda":http://github.com/thoughtbot/shoulda does. Since TestUnit already implements all generators required by Rails and shoulda just wants to overwrite part of it, there is no need for shoulda to reimplement some generators again, it can simply tell Rails to use a +TestUnit+ generator if none was found under the +Shoulda+ namespace.
316
316
 
317
317
  We can easily simulate this behavior by changing our +config/application.rb+ once again:
318
318
 
@@ -324,11 +324,11 @@ config.generators do |g|
324
324
  g.stylesheets false
325
325
 
326
326
  # Add a fallback!
327
- g.fallbacks[:should] = :test_unit
327
+ g.fallbacks[:shoulda] = :test_unit
328
328
  end
329
329
  </ruby>
330
330
 
331
- Now, if create a Comment scaffold, you will see that shoulda generators are being invoked, and at the end, they are just falling back to test unit generators:
331
+ Now, if you create a Comment scaffold, you will see that the shoulda generators are being invoked, and at the end, they are just falling back to test unit generators:
332
332
 
333
333
  <shell>
334
334
  $ rails generate scaffold Comment body:text
@@ -357,7 +357,7 @@ $ rails generate scaffold Comment body:text
357
357
  create test/unit/helpers/comments_helper_test.rb
358
358
  </shell>
359
359
 
360
- Such tool allows your generators to have single responsibility, increasing the code reuse and reducing the amount of duplication.
360
+ Fallbacks allow your generators to have a single responsibility, increasing code reuse and reducing the amount of duplication.
361
361
 
362
362
  h3. Changelog
363
363