aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source/4_0_release_notes.textile
blob: 8d13c590807004a4a1d861ea44e8f8421072a521 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
h2. Ruby on Rails 4.0 Release Notes

Highlights in Rails 4.0:

These release notes cover the major changes, but do not include each bug-fix and changes. If you want to see everything, check out the "list of commits":https://github.com/rails/rails/commits/master in the main Rails repository on GitHub.

endprologue.

h3. Upgrading to Rails 4.0

TODO. This is a WIP guide.

If you're upgrading an existing application, it's a great idea to have good test coverage before going in. You should also first upgrade to Rails 3.2 in case you haven't and make sure your application still runs as expected before attempting an update to Rails 4.0. Then take heed of the following changes:

h4. Rails 3.2 requires at least Ruby 1.9.3

Rails 3.2 requires Ruby 1.9.3 or higher. Support for all of the previous Ruby versions has been dropped officially and you should upgrade as early as possible.

h4. What to update in your apps

* Update your Gemfile to depend on
** <tt>rails = 4.0.0</tt>
** <tt>sass-rails ~> 3.2.3</tt>
** <tt>coffee-rails ~> 3.2.1</tt>
** <tt>uglifier >= 1.0.3</tt>

TODO: Update the versions above.

* Rails 4.0 removes <tt>vendor/plugins</tt> completely. You have to replace these plugins by extracting them as gems and adding them in your Gemfile. If you choose not to make them gems, you can move them into, say, <tt>lib/my_plugin/*</tt> and add an appropriate initializer in <tt>config/initializers/my_plugin.rb</tt>.

TODO: Configuration changes in environment files

h3. Creating a Rails 4.0 application

<shell>
# You should have the 'rails' rubygem installed
$ rails new myapp
$ cd myapp
</shell>

h4. Vendoring Gems

Rails now uses a +Gemfile+ in the application root to determine the gems you require for your application to start. This +Gemfile+ is processed by the "Bundler":https://github.com/carlhuda/bundler gem, which then installs all your dependencies. It can even install all the dependencies locally to your application so that it doesn't depend on the system gems.

More information: "Bundler homepage":http://gembundler.com

h4. Living on the Edge

+Bundler+ and +Gemfile+ makes freezing your Rails application easy as pie with the new dedicated +bundle+ command. If you want to bundle straight from the Git repository, you can pass the +--edge+ flag:

<shell>
$ rails new myapp --edge
</shell>

If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the +--dev+ flag:

<shell>
$ ruby /path/to/rails/railties/bin/rails new myapp --dev
</shell>

h3. Major Features

h3. Documentation

h3. Railties

* Add runner to <tt>Rails::Railtie</tt> as a hook called just after runner starts.

* Add <tt>/rails/info/routes</tt> path which displays the same information as +rake routes+.

* Improved +rake routes+ output for redirects.

* Load all environments available in config.paths["config/environments"].

* The application generator generates <tt>public/humans.txt</tt> with some basic data.

* Add <tt>config.queue_consumer</tt> to allow the default consumer to be configurable.

* Add <tt>Rails.queue</tt> as an interface with a default implementation that consumes jobs in a separate thread.

* Remove <tt>Rack::SSL</tt> in favour of <tt>ActionDispatch::SSL</tt>.

* Allow to set class that will be used to run as a console, other than IRB, with <tt>Rails.application.config.console=</tt>. It's best to add it to console block.

<ruby>
# it can be added to config/application.rb
console do
  # this block is called only when running console,
  # so we can safely require pry here
  require "pry"
  config.console = Pry
end
</ruby>

* Add convenience hide! method to Rails generators to hide current generator
  namespace from showing when running rails generate.

* Scaffold now uses +content_tag_for+ in <tt>index.html.erb</tt>.

* <tt>Rails::Plugin</tt> is removed. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies.

h4(#railties_deprecations). Deprecations

h3. Action Mailer

* No changes.

h3. Action Pack

h4. Action Controller

* Extracted redirect logic from <tt>ActionController::ForceSSL::ClassMethods.force_ssl</tt>  into <tt>ActionController::ForceSSL#force_ssl_redirect</tt>.

* URL path parameters with invalid encoding now raise <tt>ActionController::BadRequest</tt>.

* Malformed query and request parameter hashes now raise <tt>ActionController::BadRequest</tt>.

* +respond_to+ and +respond_with+ now raise <tt>ActionController::UnknownFormat</tt> instead of directly returning head 406. The exception is rescued and converted to 406 in the exception handling middleware.

* JSONP now uses mimetype <tt>application/javascript</tt> instead of <tt>application/json</tt>.

* Session arguments passed to process calls in functional tests are now merged into the existing session, whereas previously they would replace the existing session.  This change may break some existing tests if they are asserting the exact contents of the session but should not break existing tests that only assert individual keys.

* Forms of persisted records use always PATCH (via the _method hack).

* For resources, both PATCH and PUT are routed to the update action.

* Don't ignore +force_ssl+ in development. This is a change of behavior - use a :if condition to recreate the old behavior.

<ruby>
class AccountsController < ApplicationController
  force_ssl :if => :ssl_configured?

  def ssl_configured?
    !Rails.env.development?
  end
end
</ruby>

h5(#actioncontroller_deprecations). Deprecations

* Deprecated ActionController::Integration in favour of ActionDispatch::Integration

* Deprecated ActionController::IntegrationTest in favour of ActionDispatch::IntegrationTest

* Deprecated ActionController::PerformanceTest in favour of ActionDispatch::PerformanceTest

* Deprecated ActionController::AbstractRequest in favour of ActionDispatch::Request

* Deprecated ActionController::Request in favour of ActionDispatch::Request

* Deprecated ActionController::AbstractResponse in favour of ActionDispatch::Response

* Deprecated ActionController::Response in favour of ActionDispatch::Response

* Deprecated ActionController::Routing in favour of ActionDispatch::Routing

h4. Action Dispatch

* Added <tt>ActionDispatch::SSL</tt> middleware that when included force all the requests to be under HTTPS protocol.

* Copy literal route constraints to defaults so that url generation know about them.  The copied constraints are :protocol, :subdomain, :domain, :host and :port.

* Allows +assert_redirected_to+ to match against a regular expression.

* Add backtrace to development routing error page.

* +assert_generates+, +assert_recognizes+, and +assert_routing+ all raise +Assertion+ instead of +RoutingError+.

* Allows the route helper root to take a string argument. For example, <tt>root 'pages#main'</tt> as a shortcut for <tt>root to: 'pages#main'</tt>.

* Adds support for the PATCH verb:
      Request objects respond to patch?.
      Routes have a new patch method, and understand :patch in the
      existing places where a verb is configured, like :via.
      New method patch available in functional tests.
      If :patch is the default verb for updates, edits are
      tunneled as PATCH rather than as PUT, and routing acts accordingly.
      New method patch_via_redirect available in integration tests.

* Integration tests support the OPTIONS method.

* +expires_in+ accepts a +must_revalidate+ flag. If true, "must-revalidate" is added to the Cache-Control header.

* Default responder will now always use your overridden block in respond_with to render your response.

* Turn off verbose mode of rack-cache, we still have X-Rack-Cache to check that info.

* Include mounted_helpers (helpers for accessing mounted engines) in <tt>ActionDispatch::IntegrationTest</tt> by default.

h5(#actiondispatch_deprecations). Deprecations

h4. Action View

* Make current object and counter (when it applies) variables accessible when rendering templates with :object / :collection.

* Allow to lazy load +default_form_builder+ by passing a String instead of a constant.

* Add index method to +FormBuilder+ class.

* Adds support for layouts when rendering a partial with a given collection.

* Remove <tt>:disable_with</tt> in favor of <tt>data-disable-with</tt> option from +submit_tag+, +button_tag+ and +button_to+ helpers.

* Remove <tt>:mouseover</tt> option from +image_tag+ helper.

* Templates without a handler extension now raises a deprecation warning but still defaults to ERb. In future releases, it will simply return the template content.

* Add divider option to +grouped_options_for_select+ to generate a separator optgroup automatically, and deprecate prompt as third argument, in favor of using an options hash.

* Add +time_field+ and +time_field_tag+ helpers which render an <tt>input[type="time"]</tt> tag.

* Removed old +text_helper+ apis for +highlight+, +excerpt+ and +word_wrap+.

* Allow to use mounted_helpers (helpers for accessing mounted engines) in <tt>ActionView::TestCase</tt>.

* Remove the leading \n added by textarea on +assert_select+.

* Changed default value for <tt>config.action_view.embed_authenticity_token_in_remote_forms</tt> to false. This change breaks remote forms that need to work also without JavaScript, so if you need such behavior, you can either set it to true or explicitly pass <tt>:authenticity_token => true</tt> in form options.

* Make possible to use a block in +button_to+ helper if button text is hard to fit into the name parameter:

<ruby>
<%= button_to [:make_happy, @user] do %>
  Make happy <strong><%= @user.name %></strong>
<% end %>
# => "<form method="post" action="/users/1/make_happy" class="button_to">
#      <div>
#        <button type="submit">
#          Make happy <strong>Name</strong>
#        </button>
#      </div>
#    </form>"
</ruby>

* Replace +include_seconds+ boolean argument with <tt>:include_seconds => true</tt> option in +distance_of_time_in_words+ and +time_ago_in_words+ signature.

* Remove +button_to_function+ and +link_to_function+ helpers.

* truncate now always returns an escaped HTML-safe string. The option :escape can be used as false to not escape the result.

* truncate now accepts a block to show extra content when the text is truncated.

* Add +week_field+, +week_field_tag+, +month_field+, +month_field_tag+, +datetime_local_field+, +datetime_local_field_tag+, +datetime_field+ and +datetime_field_tag+ helpers.

* Add +color_field+ and +color_field_tag+ helpers.

* Add +include_hidden+ option to select tag. With <tt>:include_hidden => false</tt> select with multiple attribute doesn't generate hidden input with blank value.

* Removed default size option from the +text_field+, +search_field+, +telephone_field+, +url_field+, +email_field+ helpers.

* Removed default cols and rows options from the +text_area+ helper.

* Adds +image_url+, +javascript_url+, +stylesheet_url+, +audio_url+, +video_url+, and +font_url+ to assets tag helper. These URL helpers will return the full path to your assets. This is useful when you are going to reference this asset from external host.

* Allow +value_method+ and +text_method+ arguments from +collection_select+ and +options_from_collection_for_select+ to receive an object that responds to :call, such as a proc, to evaluate the option in the current element context. This works the same way with +collection_radio_buttons+ and +collection_check_boxes+.

* Add +date_field+ and +date_field_tag+ helpers which render an <tt>input[type="date"]</tt> tag.

* Add +collection_check_boxes+ form helper, similar to +collection_select+:

<ruby>
collection_check_boxes :post, :author_ids, Author.all, :id, :name
# Outputs something like:
<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" />
<label for="post_author_ids_1">D. Heinemeier Hansson</label>
<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
<label for="post_author_ids_2">D. Thomas</label>
<input name="post[author_ids][]" type="hidden" value="" />
</ruby>

The label/check_box pairs can be customized with a block.

* Add +collection_radio_buttons+ form helper, similar to collection_select:

<ruby>
collection_radio_buttons :post, :author_id, Author.all, :id, :name
# Outputs something like:
<input id="post_author_id_1" name="post[author_id]" type="radio" value="1" />
<label for="post_author_id_1">D. Heinemeier Hansson</label>
<input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
<label for="post_author_id_2">D. Thomas</label>
</ruby>

The label/radio_button pairs can be customized with a block.

* +check_box+ with :form HTML5 attribute will now replicate the :form attribute to the hidden field as well.

* label form helper accepts :for => nil to not generate the attribute.

* Add :format option to +number_to_percentage+.

* Add <tt>config.action_view.logger</tt> to configure logger for Action View.

* +check_box+ helper with :disabled => true will generate a disabled hidden field to conform with the HTML convention where disabled fields are not submitted with the form. This is a behavior change, previously the hidden tag had a value of the disabled checkbox.

* +favicon_link_tag+ helper will now use the favicon in <tt>app/assets</tt> by default.

* <tt>ActionView::Helpers::TextHelper#highlight</tt> now defaults to the HTML5 +mark+ element.

h5(#actionview_deprecations). Deprecations

h4. Sprockets

Moved into a separate gem <tt>sprockets-rails</tt>.

h3. Active Record

* Allow blocks for count with <tt>ActiveRecord::Relation</tt>, to work similar as <tt>Array#count</tt>: <tt>Person.where("age > 26").count { |person| person.gender == 'female' }</tt>

* Added support to <tt>CollectionAssociation#delete</tt> for passing fixnum or string values as record ids. This finds the records responding to the id and executes delete on them.

<ruby>
class Person < ActiveRecord::Base
  has_many :pets
end

person.pets.delete("1")  # => [#<Pet id: 1>]
person.pets.delete(2, 3) # => [#<Pet id: 2>, #<Pet id: 3>]
</ruby>

* It's not possible anymore to destroy a model marked as read only.

* Added ability to <tt>ActiveRecord::Relation#from</tt> to accept other <tt>ActiveRecord::Relation</tt> objects.

* Added custom coders support for <tt>ActiveRecord::Store</tt>. Now you can set your custom coder like this:

<ruby>store :settings, accessors: [ :color, :homepage ], coder: JSON</ruby>

* mysql and mysql2 connections will set SQL_MODE=STRICT_ALL_TABLES by default to avoid silent data loss. This can be disabled by specifying strict: false in your database.yml.

* Added default order to first to assure consistent results among diferent database engines. Introduced take as a replacement to the old behavior of first.

* Added an :index option to automatically create indexes for references and belongs_to statements in migrations. The references and belongs_to methods now support an index option that receives either a boolean value or an options hash that is identical to options available to the add_index method:

<ruby>
create_table :messages do |t|
  t.references :person, :index => true
end
</ruby>

Is the same as:

<ruby>
create_table :messages do |t|
  t.references :person
end
add_index :messages, :person_id
</ruby>

Generators have also been updated to use the new syntax.

* Added bang methods for mutating <tt>ActiveRecord::Relation</tt> objects. For example, while <tt>foo.where(:bar)</tt> will return a new object leaving foo unchanged, <tt>foo.where!(:bar)</tt> will mutate the foo object.

* Added #find_by and #find_by! to mirror the functionality provided by dynamic finders in a way that allows dynamic input more easily:

<ruby>
Post.find_by name: 'Spartacus', rating: 4
Post.find_by "published_at < ?", 2.weeks.ago
Post.find_by! name: 'Spartacus'
</ruby>

* Added <tt>ActiveRecord::Base#slice</tt> to return a hash of the given methods with their names as keys and returned values as values.

* Remove IdentityMap - IdentityMap has never graduated to be an "enabled-by-default" feature, due to some inconsistencies with associations, as described in this commit: https://github.com/rails/rails/commit/302c912bf6bcd0fa200d964ec2dc4a44abe328a6. Hence the removal from the codebase, until such issues are fixed.

* Added a feature to dump/load internal state of SchemaCache instance because we want to boot rails more quickly when we have many models.

<ruby>
# execute rake task.
RAILS_ENV=production bundle exec rake db:schema:cache:dump
=> generate db/schema_cache.dump

# add config.use_schema_cache_dump = true in config/production.rb. BTW, true is default.

# boot rails.
RAILS_ENV=production bundle exec rails server
=> use db/schema_cache.dump

# If you remove clear dumped cache, execute rake task.
RAILS_ENV=production bundle exec rake db:schema:cache:clear
=> remove db/schema_cache.dump
</ruby>

* Added support for partial indices to PostgreSQL adapter.

* The +add_index+ method now supports a +where+ option that receives a string with the partial index criteria.

* Implemented <tt>ActiveRecord::Relation#none</tt> method which returns a chainable relation with zero records (an instance of the NullRelation class). Any subsequent condition chained to the returned relation will continue generating an empty relation and will not fire any query to the database.

* Added the <tt>ActiveRecord::NullRelation</tt> class implementing the null object pattern for the Relation class.

* Added +create_join_table+ migration helper to create HABTM join tables.

<ruby>
create_join_table :products, :categories
# =>
# create_table :categories_products, :id => false do |td|
#   td.integer :product_id, :null => false
#   td.integer :category_id, :null => false
# end
</ruby>

* The primary key is always initialized in the @attributes hash to nil (unless another value has been specified).

* In previous releases, the following would generate a single query with an OUTER JOIN comments, rather than two separate queries:

<ruby>Post.includes(:comments).where("comments.name = 'foo'")</ruby>

This behaviour relies on matching SQL string, which is an inherently flawed idea unless we write an SQL parser, which we do not wish to do. Therefore, it is now deprecated.

To avoid deprecation warnings and for future compatibility, you must explicitly state which tables you reference, when using SQL snippets:

<ruby>Post.includes(:comments).where("comments.name = 'foo'").references(:comments)</ruby>

Note that you do not need to explicitly specify references in the following cases, as they can be automatically inferred:

<ruby>
Post.where(comments: { name: 'foo' })
Post.where('comments.name' => 'foo')
Post.order('comments.name')
</ruby>

You also do not need to worry about this unless you are doing eager loading. Basically, don't worry unless you see a deprecation warning or (in future releases) an SQL error due to a missing JOIN.

* Support for the +schema_info+ table has been dropped. Please switch to +schema_migrations+.

* Connections *must* be closed at the end of a thread. If not, your connection pool can fill and an exception will be raised.

* Added the <tt>ActiveRecord::Model</tt> module which can be included in a class as an alternative to inheriting from <tt>ActiveRecord::Base</tt>:

<ruby>
class Post
  include ActiveRecord::Model
end
</ruby>

* PostgreSQL hstore records can be created.

* PostgreSQL hstore types are automatically deserialized from the database.

h4(#activerecord_deprecations). Deprecations

* Deprecated most of the 'dynamic finder' methods. All dynamic methods except for +find_by_...+ and +find_by_...!+ are deprecated. Here's how you can rewrite the code:

<ruby>
find_all_by_... can be rewritten using where(...)
find_last_by_... can be rewritten using where(...).last
scoped_by_... can be rewritten using where(...)
find_or_initialize_by_... can be rewritten using where(...).first_or_initialize
find_or_create_by_... can be rewritten using where(...).first_or_create
find_or_create_by_...! can be rewritten using where(...).first_or_create!
</ruby>

The implementation of the deprecated dynamic finders has been moved to the +active_record_deprecated_finders+ gem.

* Deprecated the old-style hash based finder API. This means that methods which previously accepted "finder options" no longer do. For example this:

<ruby>Post.find(:all, :conditions => { :comments_count => 10 }, :limit => 5)</ruby>

should be rewritten in the new style which has existed since Rails 3:

<ruby>Post.where(comments_count: 10).limit(5)</ruby>

Note that as an interim step, it is possible to rewrite the above as:

<ruby>Post.scoped(:where => { :comments_count => 10 }, :limit => 5)</ruby>

This could save you a lot of work if there is a lot of old-style finder usage in your application.

Calling <tt>Post.scoped(options)</tt> is a shortcut for <tt>Post.scoped.merge(options)</tt>. <tt>Relation#merge</tt> now accepts a hash of options, but they must be identical to the names of the equivalent finder method. These are mostly identical to the old-style finder option names, except in the following cases:

<plain>
:conditions becomes :where
:include becomes :includes
:extend becomes :extending
</plain>

The code to implement the deprecated features has been moved out to the +active_record_deprecated_finders+ gem. This gem is a dependency of Active Record in Rails 4.0. It will no longer be a dependency from Rails 4.1, but if your app relies on the deprecated features then you can add it to your own Gemfile. It will be maintained by the Rails core team until Rails 5.0 is released.

* Deprecate eager-evaluated scopes.

  Don't use this:

      scope :red, where(color: 'red')
      default_scope where(color: 'red')

  Use this:

      scope :red, -> { where(color: 'red') }
      default_scope { where(color: 'red') }

  The former has numerous issues. It is a common newbie gotcha to do the following:

      scope :recent, where(published_at: Time.now - 2.weeks)

  Or a more subtle variant:

      scope :recent, -> { where(published_at: Time.now - 2.weeks) }
      scope :recent_red, recent.where(color: 'red')

  Eager scopes are also very complex to implement within Active Record, and there are still bugs. For example, the following does not do what you expect:

      scope :remove_conditions, except(:where)
      where(...).remove_conditions # => still has conditions

* Added deprecation for the :dependent => :restrict association option.

* Up until now has_many and has_one, :dependent => :restrict option raised a DeleteRestrictionError at the time of destroying the object. Instead, it will add an error on the model.

* To fix this warning, make sure your code isn't relying on a DeleteRestrictionError and then add config.active_record.dependent_restrict_raises = false to your application config.

* New rails application would be generated with the config.active_record.dependent_restrict_raises = false in the application config.

h3. Active Model

* Passing false hash values to +validates+ will no longer enable the corresponding validators.

* +ConfirmationValidator+ error messages will attach to <tt>:#{attribute}_confirmation</tt> instead of +attribute+.

* Added <tt>ActiveModel::Model</tt>, a mixin to make Ruby objects work with Action Pack out of the box.

* <tt>ActiveModel::Errors#to_json</tt> supports a new parameter <tt>:full_messages</tt>.

* Trims down the API by removing <tt>valid?</tt> and <tt>errors.full_messages</tt>.

h4(#activemodel_deprecations). Deprecations

h3. Active Resource

* Active Resource is removed from Rails 4.0 and is now a separate gem. TODO: put a link to the gem here.

h3. Active Support

* <tt>ActionView::Helpers::NumberHelper</tt> methods have been moved to <tt>ActiveSupport::NumberHelper</tt> and are now available via <tt>Numeric#to_s</tt>.

* <tt>Numeric#to_s</tt> now accepts the formatting options :phone, :currency, :percentage, :delimited, :rounded, :human, and :human_size.

* Add <tt>Hash#transform_keys</tt>, <tt>Hash#transform_keys!</tt>, <tt>Hash#deep_transform_keys</tt> and <tt>Hash#deep_transform_keys!</tt>.

* Changed xml type datetime to dateTime (with upper case letter T).

* Add <tt>:instance_accessor</tt> option for <tt>class_attribute</tt>.

* +constantize+ now looks in the ancestor chain.

* Add <tt>Hash#deep_stringify_keys</tt> and <tt>Hash#deep_stringify_keys!</tt> to convert all keys from a +Hash+ instance into strings.

* Add <tt>Hash#deep_symbolize_keys</tt> and <tt>Hash#deep_symbolize_keys!</tt> to convert all keys from a +Hash+ instance into symbols.

* <tt>Object#try</tt> can't call private methods.

* AS::Callbacks#run_callbacks remove key argument.

* +deep_dup+ works more expectedly now and duplicates also values in +Hash+ instances and elements in +Array+ instances.

* Inflector no longer applies ice -> ouse to words like slice, police.

* Add <tt>ActiveSupport::Deprecations.behavior = :silence</tt> to completely ignore Rails runtime deprecations.

* Make <tt>Module#delegate</tt> stop using send - can no longer delegate to private methods.

* AS::Callbacks deprecate :rescuable option.

* Adds <tt>Integer#ordinal</tt> to get the ordinal suffix string of an integer.

* AS::Callbacks :per_key option is no longer supported.

* AS::Callbacks#define_callbacks add :skip_after_callbacks_if_terminated option.

* Add html_escape_once to ERB::Util, and delegate escape_once tag helper to it.

* Remove <tt>ActiveSupport::TestCase#pending</tt> method, use +skip+ instead.

* Deletes the compatibility method <tt>Module#method_names</tt>, use <tt>Module#methods</tt> from now on (which returns symbols).

* Deletes the compatibility method <tt>Module#instance_method_names</tt>, use <tt>Module#instance_methods</tt> from now on (which returns symbols).

* Unicode database updated to 6.1.0.

* Adds +encode_big_decimal_as_string+ option to force JSON serialization of BigDecimals as numeric instead of wrapping them in strings for safety.

h4(#activesupport_deprecations). Deprecations

* <tt>BufferedLogger</tt> is deprecated.  Use <tt>ActiveSupport::Logger</tt> or the +logger+ from Ruby stdlib.

* Deprecates the compatibility method <tt>Module#local_constant_names</tt> and use <tt>Module#local_constants</tt> instead (which returns symbols).

h3. Credits

See the "full list of contributors to Rails":http://contributors.rubyonrails.org/ for the many people who spent many hours making Rails, the stable and robust framework it is. Kudos to all of them.