railties 3.0.20 → 3.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. data/CHANGELOG +36 -49
  2. data/README.rdoc +2 -1
  3. data/guides/assets/stylesheets/fixes.css +16 -0
  4. data/guides/rails_guides.rb +2 -2
  5. data/guides/rails_guides/generator.rb +8 -3
  6. data/guides/rails_guides/textile_extensions.rb +4 -2
  7. data/guides/source/2_2_release_notes.textile +3 -3
  8. data/guides/source/2_3_release_notes.textile +2 -2
  9. data/guides/source/3_0_release_notes.textile +14 -14
  10. data/guides/source/action_controller_overview.textile +54 -79
  11. data/guides/source/action_mailer_basics.textile +39 -9
  12. data/guides/source/action_view_overview.textile +257 -211
  13. data/guides/source/active_record_basics.textile +1 -1
  14. data/guides/source/active_record_querying.textile +217 -27
  15. data/guides/source/active_record_validations_callbacks.textile +94 -25
  16. data/guides/source/active_support_core_extensions.textile +109 -77
  17. data/guides/source/ajax_on_rails.textile +15 -150
  18. data/guides/source/api_documentation_guidelines.textile +12 -12
  19. data/guides/source/association_basics.textile +74 -60
  20. data/guides/source/caching_with_rails.textile +59 -60
  21. data/guides/source/command_line.textile +46 -47
  22. data/guides/source/configuring.textile +55 -37
  23. data/guides/source/contribute.textile +7 -7
  24. data/guides/source/contributing_to_ruby_on_rails.textile +14 -23
  25. data/guides/source/credits.html.erb +3 -3
  26. data/guides/source/debugging_rails_applications.textile +59 -46
  27. data/guides/source/form_helpers.textile +76 -31
  28. data/guides/source/generators.textile +39 -40
  29. data/guides/source/getting_started.textile +73 -94
  30. data/guides/source/i18n.textile +64 -58
  31. data/guides/source/index.html.erb +3 -3
  32. data/guides/source/initialization.textile +634 -3284
  33. data/guides/source/layout.html.erb +6 -7
  34. data/guides/source/layouts_and_rendering.textile +59 -60
  35. data/guides/source/migrations.textile +63 -59
  36. data/guides/source/nested_model_forms.textile +2 -2
  37. data/guides/source/performance_testing.textile +16 -16
  38. data/guides/source/plugins.textile +236 -1280
  39. data/guides/source/rails_application_templates.textile +37 -29
  40. data/guides/source/rails_on_rack.textile +4 -9
  41. data/guides/source/routing.textile +96 -75
  42. data/guides/source/ruby_on_rails_guides_guidelines.textile +19 -12
  43. data/guides/source/security.textile +57 -30
  44. data/guides/source/testing.textile +26 -24
  45. data/guides/w3c_validator.rb +2 -2
  46. data/lib/rails.rb +1 -7
  47. data/lib/rails/application.rb +46 -76
  48. data/lib/rails/application/bootstrap.rb +6 -11
  49. data/lib/rails/application/configuration.rb +43 -40
  50. data/lib/rails/application/finisher.rb +16 -4
  51. data/lib/rails/application/railties.rb +6 -24
  52. data/lib/rails/application/routes_reloader.rb +45 -0
  53. data/lib/rails/backtrace_cleaner.rb +1 -1
  54. data/lib/rails/cli.rb +7 -5
  55. data/lib/rails/commands.rb +27 -2
  56. data/lib/rails/commands/application.rb +14 -1
  57. data/lib/rails/commands/benchmarker.rb +3 -1
  58. data/lib/rails/commands/dbconsole.rb +2 -2
  59. data/lib/rails/commands/destroy.rb +3 -1
  60. data/lib/rails/commands/generate.rb +3 -1
  61. data/lib/rails/commands/plugin.rb +2 -7
  62. data/lib/rails/commands/plugin_new.rb +10 -0
  63. data/lib/rails/commands/profiler.rb +3 -1
  64. data/lib/rails/commands/server.rb +4 -0
  65. data/lib/rails/configuration.rb +8 -81
  66. data/lib/rails/console/app.rb +2 -2
  67. data/lib/rails/engine.rb +460 -78
  68. data/lib/rails/engine/configuration.rb +46 -49
  69. data/lib/rails/engine/railties.rb +33 -0
  70. data/lib/rails/generators.rb +11 -5
  71. data/lib/rails/generators/actions.rb +2 -27
  72. data/lib/rails/generators/app_base.rb +216 -0
  73. data/lib/rails/generators/base.rb +3 -2
  74. data/lib/rails/generators/erb/scaffold/templates/index.html.erb +1 -1
  75. data/lib/rails/generators/generated_attribute.rb +2 -1
  76. data/lib/rails/generators/migration.rb +6 -2
  77. data/lib/rails/generators/named_base.rb +79 -3
  78. data/lib/rails/generators/rails/app/app_generator.rb +44 -209
  79. data/lib/rails/generators/rails/app/templates/Gemfile +15 -31
  80. data/lib/rails/generators/rails/app/templates/README +2 -2
  81. data/lib/rails/generators/rails/app/templates/Rakefile +1 -1
  82. data/lib/rails/generators/rails/app/templates/{public → app/assets}/images/rails.png +0 -0
  83. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +8 -0
  84. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +5 -0
  85. data/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +0 -0
  86. data/lib/rails/generators/rails/app/templates/app/models/.empty_directory +0 -0
  87. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +4 -4
  88. data/lib/rails/generators/rails/app/templates/config/application.rb +19 -3
  89. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +4 -4
  90. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +11 -6
  91. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml +3 -3
  92. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +1 -1
  93. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +1 -2
  94. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +14 -11
  95. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +5 -1
  96. data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +1 -1
  97. data/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt +12 -0
  98. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +1 -1
  99. data/lib/rails/generators/rails/app/templates/config/routes.rb +1 -1
  100. data/lib/rails/generators/rails/app/templates/db/{seeds.rb → seeds.rb.tt} +2 -2
  101. data/lib/rails/generators/rails/app/templates/public/index.html +10 -8
  102. data/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory +0 -0
  103. data/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory +0 -0
  104. data/lib/rails/generators/rails/app/templates/test/functional/.empty_directory +0 -0
  105. data/lib/rails/generators/rails/app/templates/test/integration/.empty_directory +0 -0
  106. data/lib/rails/generators/rails/app/templates/test/{test_helper.rb.tt → test_helper.rb} +0 -0
  107. data/lib/rails/generators/rails/app/templates/test/unit/.empty_directory +0 -0
  108. data/lib/rails/generators/rails/assets/USAGE +20 -0
  109. data/lib/rails/generators/rails/assets/assets_generator.rb +39 -0
  110. data/lib/rails/generators/rails/assets/templates/javascript.js +2 -0
  111. data/lib/rails/generators/rails/assets/templates/javascript.js.coffee +3 -0
  112. data/lib/rails/generators/rails/assets/templates/stylesheet.css +4 -0
  113. data/lib/rails/generators/rails/assets/templates/stylesheet.css.scss +5 -0
  114. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
  115. data/lib/rails/generators/rails/controller/templates/controller.rb +2 -0
  116. data/lib/rails/generators/rails/generator/generator_generator.rb +2 -2
  117. data/lib/rails/generators/rails/generator/templates/templates/.empty_directory +0 -0
  118. data/lib/rails/generators/rails/helper/templates/helper.rb +2 -0
  119. data/lib/rails/generators/rails/plugin/plugin_generator.rb +7 -0
  120. data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +4 -4
  121. data/lib/rails/generators/rails/plugin_new/USAGE +10 -0
  122. data/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +303 -0
  123. data/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +9 -0
  124. data/lib/rails/generators/rails/plugin_new/templates/Gemfile +11 -0
  125. data/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE +20 -0
  126. data/lib/rails/generators/rails/plugin_new/templates/README.rdoc +3 -0
  127. data/lib/rails/generators/rails/plugin_new/templates/Rakefile +21 -0
  128. data/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt +4 -0
  129. data/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt +4 -0
  130. data/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory +0 -0
  131. data/lib/rails/generators/rails/plugin_new/templates/config/routes.rb +6 -0
  132. data/lib/rails/generators/rails/plugin_new/templates/gitignore +6 -0
  133. data/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb +6 -0
  134. data/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb +7 -0
  135. data/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake +4 -0
  136. data/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +16 -0
  137. data/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb +10 -0
  138. data/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb +4 -0
  139. data/lib/rails/generators/rails/plugin_new/templates/script/rails.tt +5 -0
  140. data/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb +7 -0
  141. data/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb +12 -0
  142. data/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb +10 -0
  143. data/lib/rails/generators/rails/resource/resource_generator.rb +2 -2
  144. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +20 -1
  145. data/lib/rails/generators/rails/{stylesheets → scaffold}/templates/scaffold.css +0 -0
  146. data/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss +58 -0
  147. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +21 -19
  148. data/lib/rails/generators/resource_helpers.rb +3 -3
  149. data/lib/rails/generators/test_case.rb +2 -20
  150. data/lib/rails/generators/test_unit/controller/templates/functional_test.rb +5 -4
  151. data/lib/rails/generators/test_unit/helper/templates/helper_test.rb +2 -0
  152. data/lib/rails/generators/test_unit/integration/templates/integration_test.rb +3 -4
  153. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb +5 -4
  154. data/lib/rails/generators/test_unit/model/templates/fixtures.yml +1 -1
  155. data/lib/rails/generators/test_unit/model/templates/unit_test.rb +5 -4
  156. data/lib/rails/generators/test_unit/observer/templates/unit_test.rb +5 -4
  157. data/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +3 -4
  158. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +7 -5
  159. data/lib/rails/info.rb +0 -1
  160. data/lib/rails/paths.rb +119 -65
  161. data/lib/rails/plugin.rb +18 -19
  162. data/lib/rails/rack/log_tailer.rb +1 -1
  163. data/lib/rails/railtie.rb +50 -47
  164. data/lib/rails/railtie/configurable.rb +20 -10
  165. data/lib/rails/railtie/configuration.rb +20 -19
  166. data/lib/rails/source_annotation_extractor.rb +5 -5
  167. data/lib/rails/tasks.rb +1 -0
  168. data/lib/rails/tasks/assets.rake +10 -0
  169. data/lib/rails/tasks/documentation.rake +2 -8
  170. data/lib/rails/tasks/engine.rake +69 -0
  171. data/lib/rails/tasks/framework.rake +4 -21
  172. data/lib/rails/tasks/misc.rake +1 -1
  173. data/lib/rails/tasks/routes.rake +2 -1
  174. data/lib/rails/test_help.rb +17 -1
  175. data/lib/rails/test_unit/railtie.rb +1 -1
  176. data/lib/rails/test_unit/testing.rake +8 -3
  177. data/lib/rails/version.rb +3 -3
  178. metadata +128 -100
  179. checksums.yaml +0 -7
  180. data/lib/rails/application/configurable.rb +0 -19
  181. data/lib/rails/console/sandbox.rb +0 -6
  182. data/lib/rails/deprecation.rb +0 -41
  183. data/lib/rails/engine/configurable.rb +0 -25
  184. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml +0 -62
  185. data/lib/rails/generators/rails/app/templates/public/javascripts/application.js +0 -2
  186. data/lib/rails/generators/rails/app/templates/public/javascripts/controls.js +0 -965
  187. data/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js +0 -974
  188. data/lib/rails/generators/rails/app/templates/public/javascripts/effects.js +0 -1123
  189. data/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js +0 -6001
  190. data/lib/rails/generators/rails/app/templates/public/javascripts/rails.js +0 -202
  191. data/lib/rails/generators/rails/stylesheets/USAGE +0 -5
  192. data/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb +0 -9
  193. data/lib/rails/info_routes.rb +0 -3
@@ -25,7 +25,7 @@ h4. Page Caching
25
25
 
26
26
  Page caching is a Rails mechanism which allows the request for a generated page to be fulfilled by the webserver (i.e. apache or nginx), without ever having to go through the Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be applied to every situation (such as pages that need authentication) and since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with.
27
27
 
28
- So, how do you enable this super-fast cache behavior? Simple, let's say you have a controller called +ProductsController+ and an +index+ action that lists all the products
28
+ So, how do you enable this super-fast cache behavior? Simple, let's say you have a controller called +ProductsController+ and an +index+ action that lists all the products
29
29
 
30
30
  <ruby>
31
31
  class ProductsController < ActionController
@@ -65,7 +65,7 @@ end
65
65
 
66
66
  If you want a more complicated expiration scheme, you can use cache sweepers to expire cached objects when things change. This is covered in the section on Sweepers.
67
67
 
68
- Note: Page caching ignores all parameters. For example +/products?page=1+ will be written out to the filesystem as +products.html+ with no reference to the +page+ parameter. Thus, if someone requests +/products?page=2+ later, they will get the cached first page. Be careful when page caching GET parameters in the URL!
68
+ NOTE: Page caching ignores all parameters. For example +/products?page=1+ will be written out to the filesystem as +products.html+ with no reference to the +page+ parameter. Thus, if someone requests +/products?page=2+ later, they will get the cached first page. Be careful when page caching GET parameters in the URL!
69
69
 
70
70
  INFO: Page caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Typically, a redirection in some before filter that checks request preconditions does the job.
71
71
 
@@ -152,7 +152,7 @@ expire_fragment('all_available_products')
152
152
 
153
153
  h4. Sweepers
154
154
 
155
- Cache sweeping is a mechanism which allows you to get around having a ton of +expire_{page,action,fragment}+ calls in your code. It does this by moving all the work required to expire cached content into an +ActionController::Caching::Sweeper+ subclass. This class is an observer and looks for changes to an object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter.
155
+ Cache sweeping is a mechanism which allows you to get around having a ton of +expire_{page,action,fragment}+ calls in your code. It does this by moving all the work required to expire cached content into an +ActionController::Caching::Sweeper+ subclass. This class is an observer and looks for changes to an object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter.
156
156
 
157
157
  Continuing with our Product controller example, we could rewrite it with a sweeper like this:
158
158
 
@@ -230,94 +230,103 @@ class ProductsController < ActionController
230
230
  end
231
231
  </ruby>
232
232
 
233
- The second time the same query is run against the database, it's not actually going to hit the database. The first time the result is returned from the query it is stored in the query cache (in memory) and the second time it's pulled from memory.
233
+ The second time the same query is run against the database, it's not actually going to hit the database. The first time the result is returned from the query it is stored in the query cache (in memory) and the second time it's pulled from memory.
234
234
 
235
- However, it's important to note that query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action. If you'd like to store query results in a more persistent fashion, you can in Rails by using low level caching.
235
+ However, it's important to note that query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action. If you'd like to store query results in a more persistent fashion, you can in Rails by using low level caching.
236
236
 
237
237
  h3. Cache Stores
238
238
 
239
239
  Rails provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk.
240
240
 
241
- Rails 2.1 and above provide +ActiveSupport::Cache::Store+ which can be used to cache strings. Some cache store implementations, like +MemoryStore+, are able to cache arbitrary Ruby objects, but don't count on every cache store to be able to do that.
241
+ h4. Configuration
242
242
 
243
- The default cache stores provided with Rails include:
244
-
245
- 1) +ActiveSupport::Cache::MemoryStore+: A cache store implementation which stores everything into memory in the same process. If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances won't be able to share cache data with each other. If your application never performs manual cache item expiry (e.g. when you‘re using generational cache keys), then using +MemoryStore+ is ok. Otherwise, consider carefully whether you should be using this cache store.
246
-
247
- +MemoryStore+ is not only able to store strings, but also arbitrary Ruby objects.
248
-
249
- +MemoryStore+ is not thread-safe. Use +SynchronizedMemoryStore+ instead if you need thread-safety.
243
+ You can set up your application's default cache store by calling +config.cache_store=+ in the Application definition inside your +config/application.rb+ file or in an Application.configure block in an environment specific configuration file (i.e. +config/environments/*.rb+). The first argument will be the cache store to use and the rest of the argument will be passed as arguments to the cache store constructor.
250
244
 
251
245
  <ruby>
252
- ActionController::Base.cache_store = :memory_store
246
+ config.cache_store = :memory_store
253
247
  </ruby>
254
248
 
255
- 2) +ActiveSupport::Cache::FileStore+: Cached data is stored on the disk, this is the default store and the default path for this store is +tmp/cache+. Works well for all types of environments and allows all processes running from the same application directory to access the cached content. If +tmp/cache+ does not exist, the default store becomes +MemoryStore+.
249
+ Alternatively, you can call +ActionController::Base.cache_store+ outside of a configuration block.
256
250
 
257
- <ruby>
258
- ActionController::Base.cache_store = :file_store, "/path/to/cache/directory"
259
- </ruby>
251
+ You can access the cache by calling +Rails.cache+.
260
252
 
261
- 3) +ActiveSupport::Cache::DRbStore+: Cached data is stored in a separate shared DRb process that all servers communicate with. This works for all environments and only keeps one cache around for all processes, but requires that you run and manage a separate DRb process.
253
+ h4. ActiveSupport::Cache::Store
262
254
 
263
- <ruby>
264
- ActionController::Base.cache_store = :drb_store, "druby://localhost:9192"
265
- </ruby>
255
+ This class provides the foundation for interacting with the cache in Rails. This is an abstract class and you cannot use it on its own. Rather you must use a concrete implementation of the class tied to a storage engine. Rails ships with several implementations documented below.
256
+
257
+ The main methods to call are +read+, +write+, +delete+, +exist?+, and +fetch+. The fetch method takes a block and will either return an existing value from the cache, or evaluate the block and write the result to the cache if no value exists.
266
258
 
267
- 4) +ActiveSupport::Cache::MemCacheStore+: Works like +DRbStore+, but uses Danga's +memcached+ instead. Rails uses the bundled +memcached-client+ gem by default. This is currently the most popular cache store for production websites.
259
+ There are some common options used by all cache implementations. These can be passed to the constructor or the various methods to interact with entries.
268
260
 
269
- Special features:
261
+ * +:namespace+ - This option can be used to create a namespace within the cache store. It is especially useful if your application shares a cache with other applications. The default value will include the application name and Rails environment.
270
262
 
271
- * Clustering and load balancing. One can specify multiple memcached servers, and +MemCacheStore+ will load balance between all available servers. If a server goes down, then +MemCacheStore+ will ignore it until it goes back online.
272
- * Time-based expiry support. See +write+ and the +:expires_in+ option.
273
- * Per-request in memory cache for all communication with the +memcached+ server(s).
263
+ * +:compress+ - This option can be used to indicate that compression should be used in the cache. This can be useful for transferring large cache entries over a slow network.
274
264
 
275
- It also accepts a hash of additional options:
265
+ * +:compress_threshold+ - This options is used in conjunction with the +:compress+ option to indicate a threshold under which cache entries should not be compressed. This defaults to 16 kilobytes.
276
266
 
277
- * +:namespace+: specifies a string that will automatically be prepended to keys when accessing the memcached store.
278
- * +:readonly+: a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write.
279
- * +:multithread+: a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality.
267
+ * +:expires_in+ - This option sets an expiration time in seconds for the cache entry when it will be automatically removed from the cache.
280
268
 
281
- The read and write methods of the +MemCacheStore+ accept an options hash too. When reading you can specify +:raw => true+ to prevent the object being marshaled (by default this is false which means the raw value in the cache is passed to +Marshal.load+ before being returned to you.)
269
+ * +:race_condition_ttl+ - This option is used in conjunction with the +:expires_in+ option. It will prevent race conditions when cache entries expire by preventing multiple processes from simultaneously regenerating the same entry (also known as the dog pile effect). This option sets the number of seconds that an expired entry can be reused while a new value is being regenerated. It's a good practice to set this value if you use the +:expires_in+ option.
282
270
 
283
- When writing to the cache it is also possible to specify +:raw => true+ means the value is not passed to +Marshal.dump+ before being stored in the cache (by default this is false).
271
+ h4. ActiveSupport::Cache::MemoryStore
284
272
 
285
- The write method also accepts an +:unless_exist+ flag which determines whether the memcached add (when true) or set (when false) method is used to store the item in the cache and an +:expires_in+ option that specifies the time-to-live for the cached item in seconds.
273
+ This cache store keeps entries in memory in the same Ruby process. The cache store has a bounded size specified by the +:size+ options to the initializer (default is 32Mb). When the cache exceeds the allotted size, a cleanup will occur and the least recently used entries will be removed.
286
274
 
287
275
  <ruby>
288
- ActionController::Base.cache_store = :mem_cache_store, "localhost"
276
+ ActionController::Base.cache_store = :memory_store, :size => 64.megabytes
289
277
  </ruby>
290
278
 
291
- 5) +ActiveSupport::Cache::SynchronizedMemoryStore+: Like +MemoryStore+ but thread-safe.
279
+ If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then your Rails server process instances won't be able to share cache data with each other. This cache store is not appropriate for large application deployments, but can work well for small, low traffic sites with only a couple of server processes or for development and test environments.
280
+
281
+ This is the default cache store implementation.
282
+
283
+ h4. ActiveSupport::Cache::FileStore
284
+
285
+ This cache store uses the file system to store entries. The path to the directory where the store files will be stored must be specified when initializing the cache.
292
286
 
293
287
  <ruby>
294
- ActionController::Base.cache_store = :synchronized_memory_store
288
+ ActionController::Base.cache_store = :file_store, "/path/to/cache/directory"
295
289
  </ruby>
296
290
 
297
- 6) +ActiveSupport::Cache::CompressedMemCacheStore+: Works just like the regular +MemCacheStore+ but uses GZip to decompress/compress on read/write.
291
+ With this cache store, multiple server processes on the same host can share a cache. Servers processes running on different hosts could share a cache by using a shared file system, but that set up would not be ideal and is not recommended. The cache store is appropriate for low to medium traffic sites that are served off one or two hosts.
292
+
293
+ Note that the cache will grow until the disk is full unless you periodically clear out old entries.
294
+
295
+ h4. ActiveSupport::Cache::MemCacheStore
296
+
297
+ This cache store uses Danga's +memcached+ server to provide a centralized cache for your application. Rails uses the bundled +memcached-client+ gem by default. This is currently the most popular cache store for production websites. It can be used to provide a single, shared cache cluster with very a high performance and redundancy.
298
+
299
+ When initializing the cache, you need to specify the addresses for all memcached servers in your cluster. If none is specified, it will assume memcached is running on the local host on the default port, but this is not an ideal set up for larger sites.
300
+
301
+ The +write+ and +fetch+ methods on this cache accept two additional options that take advantage of features specific to memcached. You can specify +:raw+ to send a value directly to the server with no serialization. The value must be a string or number. You can use memcached direct operation like +increment+ and +decrement+ only on raw values. You can also specify +:unless_exist+ if you don't want memcached to overwrite an existing entry.
298
302
 
299
303
  <ruby>
300
- ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost"
304
+ ActionController::Base.cache_store = :mem_cache_store, "cache-1.example.com", "cache-2.example.com"
301
305
  </ruby>
302
306
 
303
- 7) Custom store: You can define your own cache store (new in Rails 2.1).
307
+ h4. Custom Cache Stores
308
+
309
+ You can create your own custom cache store by simply extending +ActiveSupport::Cache::Store+ and implementing the appropriate methods. In this way, you can swap in any number of caching technologies into your Rails application.
310
+
311
+ To use a custom cache store, simple set the cache store to a new instance of the class.
304
312
 
305
313
  <ruby>
306
- ActionController::Base.cache_store = MyOwnStore.new("parameter")
314
+ ActionController::Base.cache_store = MyCacheStore.new
307
315
  </ruby>
308
316
 
309
- NOTE: +config.cache_store+ can be used in place of +ActionController::Base.cache_store+ in your +Rails::Initializer.run+ block in +environment.rb+
317
+ h4. Cache Keys
310
318
 
311
- In addition to all of this, Rails also adds the +ActiveRecord::Base#cache_key+ method that generates a key using the class name, +id+ and +updated_at+ timestamp (if available).
319
+ The keys used in a cache can be any object that responds to either +:cache_key+ or to +:to_param+. You can implement the +:cache_key+ method on your classes if you need to generate custom keys. ActiveRecord will generate keys based on the class name and record id.
312
320
 
313
- You can access these cache stores at a low level for storing queries and other objects. Here's an example:
321
+ You can use Hashes and Arrays of values as cache keys.
314
322
 
315
323
  <ruby>
316
- Rails.cache.read("city") # => nil
317
- Rails.cache.write("city", "Duckburgh")
318
- Rails.cache.read("city") # => "Duckburgh"
324
+ # This is a legal cache key
325
+ Rails.cache.read(:site => "mysite", :owners => [owner_1, owner_2])
319
326
  </ruby>
320
327
 
328
+ The keys you use on +Rails.cache+ will not be the same as those actually used with the storage engine. They may be modified with a namespace or altered to fit technology backend constraints. This means, for instance, that you can't save values with +Rails.cache+ and then try to pull them out with the +memcache-client+ gem. However, you also don't need to worry about exceeding the memcached size limit or violating syntax rules.
329
+
321
330
  h3. Conditional GET support
322
331
 
323
332
  Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn't changed since the last request and can be safely pulled from the browser cache.
@@ -343,7 +352,7 @@ class ProductsController < ApplicationController
343
352
  # If the request is fresh (i.e. it's not modified) then you don't need to do
344
353
  # anything. The default render checks for this using the parameters
345
354
  # used in the previous call to stale? and will automatically send a
346
- # :not_modified. So that's it, you're done.
355
+ # :not_modified. So that's it, you're done.
347
356
  end
348
357
  </ruby>
349
358
 
@@ -362,24 +371,14 @@ class ProductsController < ApplicationController
362
371
  end
363
372
  </ruby>
364
373
 
365
- h3. Advanced Caching
366
-
367
- Along with the built-in mechanisms outlined above, a number of excellent plugins exist to help with finer grained control over caching. These include Chris Wanstrath's excellent cache_fu plugin (more info "here":http://errtheblog.com/posts/57-kickin-ass-w-cachefu ) and Evan Weaver's interlock plugin (more info "here":http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/ ). Both of these plugins play nice with memcached and are a must-see for anyone
368
- seriously considering optimizing their caching needs.
369
-
370
- Also the new "Cache money":http://github.com/nkallen/cache-money/tree/master plugin is supposed to be mad cool.
371
-
372
- h3. References
374
+ h3. Further reading
373
375
 
374
376
  * "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails
375
- * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial
376
- * "RailsEnvy, Rails Caching Tutorial, Part 2":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2
377
- * "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html
378
- * "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching
379
377
 
380
378
 
381
379
  h3. Changelog
382
380
 
381
+ * Feb 17, 2011: Document 3.0.0 changes to ActiveSupport::Cache
383
382
  * May 02, 2009: Formatting cleanups
384
383
  * April 26, 2009: Clean up typos in submitted patch
385
384
  * April 1, 2009: Made a bunch of small fixes
@@ -8,10 +8,10 @@ Rails comes with every command line tool you'll need to
8
8
  * Mess with objects through an interactive shell
9
9
  * Profile and benchmark your new creation
10
10
 
11
- NOTE: This tutorial assumes you have basic Rails knowledge from reading the "Getting Started with Rails Guide":getting_started.html.
12
-
13
11
  endprologue.
14
12
 
13
+ NOTE: This tutorial assumes you have basic Rails knowledge from reading the "Getting Started with Rails Guide":getting_started.html.
14
+
15
15
  WARNING. This Guide is based on Rails 3.0. Some of the code shown here will not work in earlier versions of Rails.
16
16
 
17
17
  h3. Command Line Basics
@@ -31,7 +31,7 @@ h4. +rails new+
31
31
 
32
32
  The first thing we'll want to do is create a new Rails application by running the +rails new+ command after installing Rails.
33
33
 
34
- WARNING: You know you need the rails gem installed by typing +gem install rails+ first, if you don't have this installed, follow the instructions in the "Rails 3 Release Notes":/3_0_release_notes.html
34
+ WARNING: You can install the rails gem by typing +gem install rails+, if you don't have it already. Follow the instructions in the "Rails 3 Release Notes":/3_0_release_notes.html
35
35
 
36
36
  <shell>
37
37
  $ rails new commandsapp
@@ -73,7 +73,7 @@ $ rails server
73
73
  [2010-04-18 03:20:33] INFO WEBrick::HTTPServer#start: pid=26086 port=3000
74
74
  </shell>
75
75
 
76
- With just three commands we whipped up a Rails server listening on port 3000. Go to your browser and open "http://localhost:3000":http://localhost:3000, you will see a basic rails app running.
76
+ With just three commands we whipped up a Rails server listening on port 3000. Go to your browser and open "http://localhost:3000":http://localhost:3000, you will see a basic Rails app running.
77
77
 
78
78
  h4. +rails generate+
79
79
 
@@ -81,7 +81,7 @@ The +rails generate+ command uses templates to create a whole lot of things. You
81
81
 
82
82
  <shell>
83
83
  $ rails generate
84
- Usage: rails generate generator [options] [args]
84
+ Usage: rails generate generator [args] [options]
85
85
 
86
86
  ...
87
87
  ...
@@ -101,11 +101,11 @@ Using generators will save you a large amount of time by writing *boilerplate co
101
101
 
102
102
  Let's make our own controller with the controller generator. But what command should we use? Let's ask the generator:
103
103
 
104
- INFO: All Rails console utilities have help text. As with most *NIX utilities, you can try adding +--help+ or +-h+ to the end, for example +rails server --help+.
104
+ INFO: All Rails console utilities have help text. As with most *nix utilities, you can try adding +--help+ or +-h+ to the end, for example +rails server --help+.
105
105
 
106
106
  <shell>
107
107
  $ rails generate controller
108
- Usage: rails generate controller ControllerName [options]
108
+ Usage: rails generate controller NAME [action action] [options]
109
109
 
110
110
  ...
111
111
  ...
@@ -122,7 +122,7 @@ Example:
122
122
  Modules Example:
123
123
  rails generate controller 'admin/credit_card' suspend late_fee
124
124
 
125
- Credit card admin controller with URLs /admin/credit_card/suspend.
125
+ Credit card admin controller with URLs like /admin/credit_card/suspend.
126
126
  Controller: app/controllers/admin/credit_card_controller.rb
127
127
  Views: app/views/admin/credit_card/debit.html.erb [...]
128
128
  Helper: app/helpers/admin/credit_card_helper.rb
@@ -134,25 +134,31 @@ The controller generator is expecting parameters in the form of +generate contro
134
134
  <shell>
135
135
  $ rails generate controller Greetings hello
136
136
  create app/controllers/greetings_controller.rb
137
+ route get "greetings/hello"
137
138
  invoke erb
138
139
  create app/views/greetings
139
140
  create app/views/greetings/hello.html.erb
140
- error rspec [not found]
141
+ invoke test_unit
142
+ create test/functional/greetings_controller_test.rb
141
143
  invoke helper
142
144
  create app/helpers/greetings_helper.rb
143
- error rspec [not found]
145
+ invoke test_unit
146
+ create test/unit/helpers/greetings_helper_test.rb
147
+ invoke assets
148
+ create app/assets/javascripts/greetings.js
149
+ create app/assets/stylesheets/greetings.css
150
+
144
151
  </shell>
145
152
 
146
- What all did this generate? It made sure a bunch of directories were in our application, and created a controller file, a functional test file, a helper for the view, and a view file.
153
+ What all did this generate? It made sure a bunch of directories were in our application, and created a controller file, a view file, a functional test file, a helper for the view, a javascript file and a stylesheet file.
147
154
 
148
- Check out the controller and modify it a little (in +app/controllers/greetings_controller.rb+):ma
155
+ Check out the controller and modify it a little (in +app/controllers/greetings_controller.rb+):
149
156
 
150
157
  <ruby>
151
158
  class GreetingsController < ApplicationController
152
159
  def hello
153
160
  @message = "Hello, how are you today?"
154
161
  end
155
-
156
162
  end
157
163
  </ruby>
158
164
 
@@ -163,7 +169,7 @@ Then the view, to display our message (in +app/views/greetings/hello.html.erb+):
163
169
  <p><%= @message %></p>
164
170
  </html>
165
171
 
166
- Deal. Go check it out in your browser. Fire up your server. Remember? +rails server+ at the root of your Rails application should do it.
172
+ Deal. Go check it out in your browser. Fire up your server using +rails server+.
167
173
 
168
174
  <shell>
169
175
  $ rails server
@@ -180,7 +186,7 @@ Rails comes with a generator for data models too:
180
186
 
181
187
  <shell>
182
188
  $ rails generate model
183
- Usage: rails generate model ModelName [field:type, field:type]
189
+ Usage: rails generate model NAME [field:type field:type] [options]
184
190
 
185
191
  ...
186
192
 
@@ -212,17 +218,17 @@ $ rails generate scaffold HighScore game:string score:integer
212
218
  create app/views/layouts/
213
219
  exists test/functional/
214
220
  create test/unit/
215
- create public/stylesheets/
221
+ create app/assets/stylesheets/
216
222
  create app/views/high_scores/index.html.erb
217
223
  create app/views/high_scores/show.html.erb
218
224
  create app/views/high_scores/new.html.erb
219
225
  create app/views/high_scores/edit.html.erb
220
226
  create app/views/layouts/high_scores.html.erb
221
- create public/stylesheets/scaffold.css
227
+ create app/assets/stylesheets/scaffold.css.scss
222
228
  create app/controllers/high_scores_controller.rb
223
229
  create test/functional/high_scores_controller_test.rb
224
230
  create app/helpers/high_scores_helper.rb
225
- route map.resources :high_scores
231
+ route resources :high_scores
226
232
  dependency model
227
233
  exists app/models/
228
234
  exists test/unit/
@@ -261,6 +267,15 @@ h4. +rails console+
261
267
 
262
268
  The +console+ command lets you interact with your Rails application from the command line. On the underside, +rails console+ uses IRB, so if you've ever used it, you'll be right at home. This is useful for testing out quick ideas with code and changing data server-side without touching the website.
263
269
 
270
+ If you wish to test out some code without changing any data, you can do that by invoking +rails console --sandbox+.
271
+
272
+ <shell>
273
+ $ rails console --sandbox
274
+ Loading development environment in sandbox (Rails 3.0.0)
275
+ Any modifications you make will be rolled back on exit
276
+ irb(main):001:0>
277
+ </shell>
278
+
264
279
  h4. +rails dbconsole+
265
280
 
266
281
  +rails dbconsole+ figures out which database you're using and drops you into whichever command line interface you would use with it (and figures out the command line parameters to give to it, too!). It supports MySQL, PostgreSQL, SQLite and SQLite3.
@@ -274,14 +289,14 @@ Let's say you're creating a website for a client who wants a small accounting sy
274
289
  There is such a thing! The plugin we're installing is called +acts_as_paranoid+, and it lets models implement a +deleted_at+ column that gets set when you call destroy. Later, when calling find, the plugin will tack on a database check to filter out "deleted" things.
275
290
 
276
291
  <shell>
277
- $ rails plugin install http://svn.techno-weenie.net/projects/plugins/acts_as_paranoid
292
+ $ rails plugin install https://github.com/technoweenie/acts_as_paranoid.git
278
293
  + ./CHANGELOG
279
294
  + ./MIT-LICENSE
280
295
  ...
281
296
  ...
282
297
  </shell>
283
298
 
284
- h4. +runner+
299
+ h4. +rails runner+
285
300
 
286
301
  <tt>runner</tt> runs Ruby code in the context of Rails non-interactively. For instance:
287
302
 
@@ -289,7 +304,7 @@ h4. +runner+
289
304
  $ rails runner "Model.long_running_method"
290
305
  </shell>
291
306
 
292
- h4. +destroy+
307
+ h4. +rails destroy+
293
308
 
294
309
  Think of +destroy+ as the opposite of +generate+. It'll figure out what generate did, and undo it. Believe you-me, the creation of this tutorial used this command many times!
295
310
 
@@ -318,7 +333,7 @@ $ rails destroy model Oops
318
333
  notempty app
319
334
  </shell>
320
335
 
321
- h4. +about+
336
+ h4. +rake about+
322
337
 
323
338
  Check it: Version numbers for Ruby, RubyGems, Rails, the Rails subcomponents, your application's folder, the current Rails environment name, your app's database adapter, and schema version! +about+ is useful when you need to ask for help, check if a security patch might affect you, or when you need some stats for an existing Rails installation.
324
339
 
@@ -341,7 +356,7 @@ Environment development
341
356
 
342
357
  h3. The Rails Advanced Command Line
343
358
 
344
- The more advanced uses of the command line are focused around finding useful (even surprising at times) options in the utilities, and fitting utilities to your needs and specific work flow. Listed here are some tricks up Rails' sleeve.
359
+ More advanced use of the command line is focused around finding useful (even surprising at times) options in the utilities, and fitting those to your needs and specific work flow. Listed here are some tricks up Rails' sleeve.
345
360
 
346
361
  h4. Rails with Databases and SCM
347
362
 
@@ -366,8 +381,8 @@ $ rails new . --git --database=postgresql
366
381
  add 'Rakefile'
367
382
  create README
368
383
  add 'README'
369
- create app/controllers/application_controller_.rb
370
- add 'app/controllers/application_controller_.rb'
384
+ create app/controllers/application_controller.rb
385
+ add 'app/controllers/application_controller.rb'
371
386
  create app/helpers/application_helper.rb
372
387
  ...
373
388
  create log/test.log
@@ -439,7 +454,7 @@ The Rails generator by default looks in these places for available generators, w
439
454
  * Inside any plugin with a directory like "generators" or "rails_generators"
440
455
  * ~/.rails/generators
441
456
  * Inside any Gem you have installed with a name ending in "_generator"
442
- * Inside *any* Gem installed with a "rails_generators" path, and a file ending in "_generator.rb"
457
+ * Inside any Gem installed with a "rails_generators" path, and a file ending in "_generator.rb"
443
458
  * Finally, the builtin Rails generators (controller, model, mailer, etc.)
444
459
 
445
460
  Let's try the fourth option (in our home directory), which will be easy to clean up later:
@@ -472,9 +487,9 @@ end
472
487
  We take whatever args are supplied, save them to an instance variable, and literally copying from the Rails source, implement a +manifest+ method, which calls +record+ with a block, and we:
473
488
 
474
489
  * Check there's a *public* directory. You bet there is.
475
- * Run the ERb template called "tutorial.erb".
490
+ * Run the ERB template called "tutorial.erb".
476
491
  * Save it into "Rails.root/public/tutorial.txt".
477
- * Pass in the arguments we saved through the +:assign+ parameter.
492
+ * Pass in the arguments we saved through the +:assigns+ parameter.
478
493
 
479
494
  Next we'll build the template:
480
495
 
@@ -527,7 +542,7 @@ Rake is a standalone Ruby utility that replaces the Unix utility 'make', and use
527
542
  You can get a list of Rake tasks available to you, which will often depend on your current directory, by typing +rake --tasks+. Each task has a description, and should help you find the thing you need.
528
543
 
529
544
  <shell>
530
- rake --tasks
545
+ $ rake --tasks
531
546
  (in /home/foobar/commandsapp)
532
547
  rake db:abort_if_pending_migrations # Raises an error if there are pending migrations
533
548
  rake db:charset # Retrieves the charset for the current environment's database
@@ -540,8 +555,6 @@ rake tmp:sessions:clear # Clears all files in tmp/sessions
540
555
  rake tmp:sockets:clear # Clears all files in tmp/sockets
541
556
  </shell>
542
557
 
543
- Let's take a look at some of these 80 or so rake tasks.
544
-
545
558
  h5. +db:+ Database
546
559
 
547
560
  The most common tasks of the +db:+ Rake namespace are +migrate+ and +create+, and it will pay off to try out all of the migration rake tasks (+up+, +down+, +redo+, +reset+). +rake db:version+ is useful when troubleshooting, telling you the current version of the database.
@@ -550,24 +563,10 @@ h5. +doc:+ Documentation
550
563
 
551
564
  If you want to strip out or rebuild any of the Rails documentation (including this guide!), the +doc:+ namespace has the tools. Stripping documentation is mainly useful for slimming your codebase, like if you're writing a Rails application for an embedded platform.
552
565
 
553
- h5. +gems:+ Ruby gems
554
-
555
- You can specify which gems your application uses, and +rake gems:install+ will install them for you. Look at your environment.rb to learn how with the *config.gem* directive.
556
-
557
- NOTE: +gems:unpack+ will unpack, that is internalize your application's Gem dependencies by copying the Gem code into your vendor/gems directory. By doing this you increase your codebase size, but simplify installation on new hosts by eliminating the need to run +rake gems:install+, or finding and installing the gems your application uses.
558
-
559
566
  h5. +notes:+ Code note enumeration
560
567
 
561
568
  These tasks will search through your code for commented lines beginning with "FIXME", "OPTIMIZE", "TODO", or any custom annotation (like XXX) and show you them.
562
569
 
563
- h5. +rails:+ Rails-specific tasks
564
-
565
- In addition to the +gems:unpack+ task above, you can also unpack the Rails backend specific gems into vendor/rails by calling +rake rails:freeze:gems+, to unpack the version of Rails you are currently using, or +rake rails:freeze:edge+ to unpack the most recent (cutting, bleeding edge) version.
566
-
567
- When you have frozen the Rails gems, Rails will prefer to use the code in vendor/rails instead of the system Rails gems. You can "thaw" by running +rake rails:unfreeze+.
568
-
569
- After upgrading Rails, it is useful to run +rails:update+, which will update your config and scripts directories, and upgrade your Rails-specific javascript (like Scriptaculous).
570
-
571
570
  h5. +test:+ Rails tests
572
571
 
573
572
  INFO: A good description of unit testing in Rails is given in "A Guide to Testing Rails Applications":testing.html
@@ -582,13 +581,13 @@ You can list all the timezones Rails knows about with +rake time:zones:all+, whi
582
581
 
583
582
  h5. +tmp:+ Temporary files
584
583
 
585
- The tmp directory is, like in the *nix /tmp directory, the holding place for temporary files like sessions (if you're using a file store for files), process id files, and cached actions. The +tmp:+ namespace tasks will help you clear them if you need to if they've become overgrown, or create them in case of an +rm -rf *+ gone awry.
584
+ The tmp directory is, like in the *nix /tmp directory, the holding place for temporary files like sessions (if you're using a file store for files), process id files, and cached actions. The +tmp:+ namespace tasks will help you clear them if you need to if they've become overgrown, or create them in case of deletions gone awry.
586
585
 
587
586
  h5. Miscellaneous Tasks
588
587
 
589
588
  +rake stats+ is great for looking at statistics on your code, displaying things like KLOCs (thousands of lines of code) and your code to test ratio.
590
589
 
591
- +rake secret+ will give you a psuedo-random key to use for your session secret.
590
+ +rake secret+ will give you a pseudo-random key to use for your session secret.
592
591
 
593
592
  +rake routes+ will list all of your defined routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with.
594
593