Skip to content
This repository

Replacing Ordered Hash to Ruby Hash #4929

Closed
wants to merge 44 commits into from

20 participants

Prasath V Ram karevn Ravil Bayramgalin Guillermo Iguaran Rafael Mendonça França Vasiliy Ermolovich Olek Janiszewski Sergey Nartimov Vijay Dev Fujimura Daisuke Simon Baird Toshinori Kajihara Manu J Aaron Patterson Trotter Cashion Carlos Antonio da Silva José Valim Stephen Celis Tomasz Zurkowski Jon Leighton
Prasath V Ram

Since Ruby 1.9 + defaults Hash works as Ordered Hash and rails 4 has minimum requirement of ruby 1.9 ++ we can replace the ActiveSupport Ordered hash to ruby hash.

karevn and others added some commits
karevn karevn Fix: when using subdomains and constraints, request params were not p…
…assed to constraints callback
d0c3df1
Ravil Bayramgalin brainopia Update time zone offset information 91dd0dd
Guillermo Iguaran guilleiguaran Update Release Notes: sprockets-rails section should be inside of Act…
…ionPack section
a2333f3
Guillermo Iguaran guilleiguaran Adding Action Mailer section to 3.2 release notes 62dae59
Rafael Mendonça França rafaelfranca Refactor button_to helper to use token_tag method c39095a
Rafael Mendonça França rafaelfranca Extract method_tag e8a21ab
Vasiliy Ermolovich nashby remove ruby 1.8 related code c47b7d2
Olek Janiszewski exviva Add ActiveRecord::Base#with_lock
Add a `with_lock` method to ActiveRecord objects, which starts
a transaction, locks the object (pessimistically) and yields to the block.
The method takes one (optional) parameter and passes it to `lock!`.

Before:

    class Order < ActiveRecord::Base
      def cancel!
        transaction do
          lock!
          # ... cancelling logic
        end
      end
    end

After:

    class Order < ActiveRecord::Base
      def cancel!
        with_lock do
          # ... cancelling logic
        end
      end
    end
76ade78
Sergey Nartimov lest refactor RAILS_CACHE deprecation
that was introduced in 6f8159c
bc9de28
prasath Refactored class methods on address render test 272f1ce
Vijay Dev vijaydev revise wording [ci skip] 12ef09f
Fujimura Daisuke fujimura update release note: timestamps is non-null as default c93299f
Simon Baird simonbaird Fix small typo in mail_to docs in url_helper.rb 19e2bc6
Toshinori Kajihara kennyj Convert URI.parser.parse to URI.parse, and remove ruby 1.8.x code. b7e88aa
Vijay Dev vijaydev select doesn't take multiple arguments - fixes #4539 [ci skip]
Also, fixed the bit about returning AM::MissingAttributeError. This
seems to be fixed earlier in 3-2-stable only.
f84079c
Vijay Dev vijaydev revising release notes [ci skip] 1133abd
Manu J j-manu Fix for log tailer when the log file doesn't exist. 1c7a699
Aaron Patterson tenderlove do not do reverse lookups on incoming requests for webrick. fixes #4542 4b21a2f
Trotter Cashion trotter Fix documentation bug in Rails::Engine 9eeb8fc
Aaron Patterson tenderlove move tagged logging to a module, stop proxying every method call c837366
Aaron Patterson tenderlove avoid useless is_a checks 6e0202f
Aaron Patterson tenderlove remove unused captures ed26322
Carlos Antonio da Silva carlosantoniodasilva Use performed? instead of checking for response_body
* Check for performed? instead of response_body
* Change performed? to return a boolean
* Refactor AC::Metal#response_body= to reuse variable
899d866
José Valim josevalim Do not deprecate performed. 6b81204
Vijay Dev vijaydev update the getting_started guide code [ci skip] d09164a
Vijay Dev vijaydev document AR::Base#with_lock in release notes [ci skip] a0977a1
Vijay Dev vijaydev fix duplicate ids for the headers [ci skip] 70db347
Vijay Dev vijaydev add uglifier version info in the 'what to update' section 5403fc7
Vijay Dev vijaydev update release notes [ci skip] d3d6dba
Stephen Celis stephencelis Don't type-cast unknown types to YAML. 139ec9b
Aaron Patterson tenderlove just use an alias. The target method is public, so make this one public
too.
4cac98a
Aaron Patterson tenderlove adding tests for previous_changes hash 868e374
Aaron Patterson tenderlove push ivar initialization down to a common method 1a4fd51
Rodrigo Flores Added format to percentage eeac7a7
Aaron Patterson tenderlove Revert "just use an alias. The target method is public, so make this …
…one public"

This reverts commit be7d224.
1f0fec8
Tomasz Zurkowski doriath Fix indentation in code example of Delegation aa871d9
Jonathan Roes document `:raise` option support for several helpers [ci skip] 4d821ed
Rafael Mendonça França rafaelfranca No need to check html_safe? twice 07d14be
Jon Leighton jonleighton Fix another race condition.
From 2c667f6.

Thanks @pwnall for the heads-up.
db815a7
Ravil Bayramgalin brainopia Removed unused assigns from ActionView::Template::Error
They existed since initial rails commit by DHH but lost use a long time
ago
1835f1f
Toshinori Kajihara kennyj Bump mail 3b3b511
Rafael Mendonça França rafaelfranca Remove code duplication d6fbe4f
Rafael Mendonça França rafaelfranca Refactor translations retrieval ad0eb7f
prasath replacing ordered hash to ruby hash ca21da7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 44 unique commits by 22 authors.

Feb 07, 2012
karevn karevn Fix: when using subdomains and constraints, request params were not p…
…assed to constraints callback
d0c3df1
Ravil Bayramgalin brainopia Update time zone offset information 91dd0dd
Guillermo Iguaran guilleiguaran Update Release Notes: sprockets-rails section should be inside of Act…
…ionPack section
a2333f3
Guillermo Iguaran guilleiguaran Adding Action Mailer section to 3.2 release notes 62dae59
Rafael Mendonça França rafaelfranca Refactor button_to helper to use token_tag method c39095a
Rafael Mendonça França rafaelfranca Extract method_tag e8a21ab
Vasiliy Ermolovich nashby remove ruby 1.8 related code c47b7d2
Olek Janiszewski exviva Add ActiveRecord::Base#with_lock
Add a `with_lock` method to ActiveRecord objects, which starts
a transaction, locks the object (pessimistically) and yields to the block.
The method takes one (optional) parameter and passes it to `lock!`.

Before:

    class Order < ActiveRecord::Base
      def cancel!
        transaction do
          lock!
          # ... cancelling logic
        end
      end
    end

After:

    class Order < ActiveRecord::Base
      def cancel!
        with_lock do
          # ... cancelling logic
        end
      end
    end
76ade78
Sergey Nartimov lest refactor RAILS_CACHE deprecation
that was introduced in 6f8159c
bc9de28
prasath Refactored class methods on address render test 272f1ce
Vijay Dev vijaydev revise wording [ci skip] 12ef09f
Fujimura Daisuke fujimura update release note: timestamps is non-null as default c93299f
Simon Baird simonbaird Fix small typo in mail_to docs in url_helper.rb 19e2bc6
Toshinori Kajihara kennyj Convert URI.parser.parse to URI.parse, and remove ruby 1.8.x code. b7e88aa
Vijay Dev vijaydev select doesn't take multiple arguments - fixes #4539 [ci skip]
Also, fixed the bit about returning AM::MissingAttributeError. This
seems to be fixed earlier in 3-2-stable only.
f84079c
Vijay Dev vijaydev revising release notes [ci skip] 1133abd
Manu J j-manu Fix for log tailer when the log file doesn't exist. 1c7a699
Aaron Patterson tenderlove do not do reverse lookups on incoming requests for webrick. fixes #4542 4b21a2f
Trotter Cashion trotter Fix documentation bug in Rails::Engine 9eeb8fc
Aaron Patterson tenderlove move tagged logging to a module, stop proxying every method call c837366
Aaron Patterson tenderlove avoid useless is_a checks 6e0202f
Aaron Patterson tenderlove remove unused captures ed26322
Carlos Antonio da Silva carlosantoniodasilva Use performed? instead of checking for response_body
* Check for performed? instead of response_body
* Change performed? to return a boolean
* Refactor AC::Metal#response_body= to reuse variable
899d866
José Valim josevalim Do not deprecate performed. 6b81204
Vijay Dev vijaydev update the getting_started guide code [ci skip] d09164a
Vijay Dev vijaydev document AR::Base#with_lock in release notes [ci skip] a0977a1
Vijay Dev vijaydev fix duplicate ids for the headers [ci skip] 70db347
Vijay Dev vijaydev add uglifier version info in the 'what to update' section 5403fc7
Vijay Dev vijaydev update release notes [ci skip] d3d6dba
Stephen Celis stephencelis Don't type-cast unknown types to YAML. 139ec9b
Aaron Patterson tenderlove just use an alias. The target method is public, so make this one public
too.
4cac98a
Aaron Patterson tenderlove adding tests for previous_changes hash 868e374
Aaron Patterson tenderlove push ivar initialization down to a common method 1a4fd51
Rodrigo Flores Added format to percentage eeac7a7
Aaron Patterson tenderlove Revert "just use an alias. The target method is public, so make this …
…one public"

This reverts commit be7d224.
1f0fec8
Tomasz Zurkowski doriath Fix indentation in code example of Delegation aa871d9
Jonathan Roes document `:raise` option support for several helpers [ci skip] 4d821ed
Rafael Mendonça França rafaelfranca No need to check html_safe? twice 07d14be
Jon Leighton jonleighton Fix another race condition.
From 2c667f6.

Thanks @pwnall for the heads-up.
db815a7
Ravil Bayramgalin brainopia Removed unused assigns from ActionView::Template::Error
They existed since initial rails commit by DHH but lost use a long time
ago
1835f1f
Toshinori Kajihara kennyj Bump mail 3b3b511
Rafael Mendonça França rafaelfranca Remove code duplication d6fbe4f
Rafael Mendonça França rafaelfranca Refactor translations retrieval ad0eb7f
prasath replacing ordered hash to ruby hash ca21da7
This page is out of date. Refresh to see the latest.

Showing 62 changed files with 485 additions and 307 deletions. Show diff stats Hide diff stats

  1. +1 1  actionmailer/actionmailer.gemspec
  2. +3 2 actionpack/CHANGELOG.md
  3. +7 3 actionpack/lib/action_controller/metal.rb
  4. +1 1  actionpack/lib/action_controller/metal/implicit_render.rb
  5. +2 1  actionpack/lib/action_dispatch/routing/route_set.rb
  6. +1 10 actionpack/lib/action_view/helpers/form_tag_helper.rb
  7. +45 54 actionpack/lib/action_view/helpers/number_helper.rb
  8. +16 6 actionpack/lib/action_view/helpers/url_helper.rb
  9. +1 0  actionpack/lib/action_view/locale/en.yml
  10. +2 3 actionpack/lib/action_view/template.rb
  11. +2 2 actionpack/lib/action_view/template/error.rb
  12. +10 8 actionpack/test/controller/addresses_render_test.rb
  13. +6 0 actionpack/test/controller/base_test.rb
  14. +0 3  actionpack/test/controller/force_ssl_test.rb
  15. +2 2 actionpack/test/controller/rescue_test.rb
  16. +14 1 actionpack/test/controller/routing_test.rb
  17. +1 1  actionpack/test/dispatch/debug_exceptions_test.rb
  18. +1 1  actionpack/test/dispatch/show_exceptions_test.rb
  19. +0 2  actionpack/test/template/html-scanner/sanitizer_test.rb
  20. +1 0  actionpack/test/template/number_helper_test.rb
  21. +2 2 actionpack/test/template/template_error_test.rb
  22. +24 3 actionpack/test/template/url_helper_test.rb
  23. +2 2 activemodel/lib/active_model/attribute_methods.rb
  24. +3 4 activemodel/lib/active_model/errors.rb
  25. +1 1  activemodel/lib/active_model/validations.rb
  26. +1 1  activemodel/test/cases/errors_test.rb
  27. +2 2 activemodel/test/cases/serializers/json_serialization_test.rb
  28. +1 1  activemodel/test/cases/validations_test.rb
  29. +28 1 activerecord/CHANGELOG.md
  30. +0 3  activerecord/lib/active_record/attribute_methods.rb
  31. +1 1  activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
  32. +8 8 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
  33. +23 16 activerecord/lib/active_record/core.rb
  34. +22 0 activerecord/lib/active_record/locking/pessimistic.rb
  35. +5 5 activerecord/lib/active_record/relation/query_methods.rb
  36. +2 2 activerecord/test/cases/adapters/sqlite3/quoting_test.rb
  37. +8 0 activerecord/test/cases/attribute_methods/read_test.rb
  38. +28 5 activerecord/test/cases/base_test.rb
  39. +20 0 activerecord/test/cases/locking_test.rb
  40. +2 2 activeresource/lib/active_resource/base.rb
  41. +2 2 activeresource/lib/active_resource/connection.rb
  42. +1 1  activesupport/lib/active_support/core_ext/date_time/calculations.rb
  43. +0 15 activesupport/lib/active_support/core_ext/date_time/conversions.rb
  44. +19 19 activesupport/lib/active_support/core_ext/module/delegation.rb
  45. +1 1  activesupport/lib/active_support/core_ext/uri.rb
  46. +32 36 activesupport/lib/active_support/tagged_logging.rb
  47. +2 6 activesupport/test/core_ext/uri_ext_test.rb
  48. +17 6 railties/guides/code/getting_started/Gemfile
  49. +9 3 railties/guides/code/getting_started/app/assets/javascripts/application.js
  50. +11 5 railties/guides/code/getting_started/app/assets/stylesheets/application.css
  51. +1 1  railties/guides/code/getting_started/app/views/layouts/application.html.erb
  52. +7 1 railties/guides/code/getting_started/config/application.rb
  53. +3 3 railties/guides/code/getting_started/config/environments/test.rb
  54. +5 0 railties/guides/code/getting_started/config/initializers/inflections.rb
  55. +4 4 railties/guides/code/getting_started/config/routes.rb
  56. +0 1  railties/guides/code/getting_started/public/500.html
  57. +44 10 railties/guides/source/3_2_release_notes.textile
  58. +11 0 railties/guides/source/active_record_querying.textile
  59. +1 0  railties/lib/rails/commands/server.rb
  60. +8 29 railties/lib/rails/deprecation.rb
  61. +1 1  railties/lib/rails/engine.rb
  62. +7 3 railties/lib/rails/rack/log_tailer.rb
2  actionmailer/actionmailer.gemspec
@@ -17,5 +17,5 @@ Gem::Specification.new do |s|
17 17 s.requirements << 'none'
18 18
19 19 s.add_dependency('actionpack', version)
20   - s.add_dependency('mail', '~> 2.4.0')
  20 + s.add_dependency('mail', '~> 2.4.1')
21 21 end
5 actionpack/CHANGELOG.md
Source Rendered
... ... @@ -1,4 +1,7 @@
1 1 ## Rails 4.0.0 (unreleased) ##
  2 +
  3 +* Add `:format` option to number_to_percentage *Rodrigo Flores*
  4 +
2 5 * Add `config.action_view.logger` to configure logger for ActionView. *Rafael França*
3 6
4 7 * Deprecated ActionController::Integration in favour of ActionDispatch::Integration
@@ -33,8 +36,6 @@
33 36
34 37 * Deprecate method_missing handling for not found actions, use action_missing instead. *Carlos Antonio da Silva*
35 38
36   -* Deprecate ActionController#performed?, check for response_body presence instead. *Carlos Antonio da Silva*
37   -
38 39 * Deprecate ActionController#rescue_action, ActionController#initialize_template_class, and ActionController#assign_shortcuts.
39 40 These methods were not being used internally anymore and are going to be removed in Rails 4. *Carlos Antonio da Silva*
40 41
10 actionpack/lib/action_controller/metal.rb
@@ -181,9 +181,13 @@ def status=(status)
181 181 @_status = Rack::Utils.status_code(status)
182 182 end
183 183
184   - def response_body=(val)
185   - body = (val.nil? || val.respond_to?(:each)) ? val : [val]
186   - super body
  184 + def response_body=(body)
  185 + body = [body] unless body.nil? || body.respond_to?(:each)
  186 + super
  187 + end
  188 +
  189 + def performed?
  190 + !!response_body
187 191 end
188 192
189 193 def dispatch(name, request) #:nodoc:
2  actionpack/lib/action_controller/metal/implicit_render.rb
@@ -2,7 +2,7 @@ module ActionController
2 2 module ImplicitRender
3 3 def send_action(method, *args)
4 4 ret = super
5   - default_render unless response_body
  5 + default_render unless performed?
6 6 ret
7 7 end
8 8
3  actionpack/lib/action_dispatch/routing/route_set.rb
@@ -579,7 +579,8 @@ def recognize_path(path, environment = {})
579 579 params[key] = URI.parser.unescape(value)
580 580 end
581 581 end
582   -
  582 + old_params = env[::ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
  583 + env[::ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] = (old_params || {}).merge(params)
583 584 dispatcher = route.app
584 585 while dispatcher.is_a?(Mapper::Constraints) && dispatcher.matches?(env) do
585 586 dispatcher = dispatcher.app
11 actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -627,7 +627,7 @@ def extra_tags_for_form(html_options)
627 627 token_tag(authenticity_token)
628 628 else
629 629 html_options["method"] = "post"
630   - tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag(authenticity_token)
  630 + method_tag(method) + token_tag(authenticity_token)
631 631 end
632 632
633 633 tags = utf8_enforcer_tag << method_tag
@@ -646,15 +646,6 @@ def form_tag_in_block(html_options, &block)
646 646 output.safe_concat("</form>")
647 647 end
648 648
649   - def token_tag(token)
650   - if token == false || !protect_against_forgery?
651   - ''
652   - else
653   - token ||= form_authenticity_token
654   - tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => token)
655   - end
656   - end
657   -
658 649 # see http://www.w3.org/TR/html4/types.html#type-name
659 650 def sanitize_to_id(name)
660 651 name.to_s.gsub(']','').gsub(/[^-a-zA-Z0-9:.]/, "_")
99 actionpack/lib/action_view/helpers/number_helper.rb
@@ -125,11 +125,10 @@ def number_to_currency(number, options = {})
125 125
126 126 options.symbolize_keys!
127 127
128   - defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
129   - currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
  128 + currency = translations_for('currency', options[:locale])
130 129 currency[:negative_format] ||= "-" + currency[:format] if currency[:format]
131 130
132   - defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency)
  131 + defaults = DEFAULT_CURRENCY_VALUES.merge(defaults_translations(options[:locale])).merge!(currency)
133 132 defaults[:negative_format] = "-" + options[:format] if options[:format]
134 133 options = defaults.merge!(options)
135 134
@@ -152,7 +151,6 @@ def number_to_currency(number, options = {})
152 151 e.number.to_s.html_safe? ? formatted_number.html_safe : formatted_number
153 152 end
154 153 end
155   -
156 154 end
157 155
158 156 # Formats a +number+ as a percentage string (e.g., 65%). You can customize the format in the +options+ hash.
@@ -169,6 +167,8 @@ def number_to_currency(number, options = {})
169 167 # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
170 168 # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator
171 169 # (defaults to +false+).
  170 + # * <tt>:format</tt> - Specifies the format of the percentage string
  171 + # The number field is <tt>%n</tt> (defaults to "%n%").
172 172 # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
173 173 #
174 174 # ==== Examples
@@ -180,6 +180,7 @@ def number_to_currency(number, options = {})
180 180 # number_to_percentage(302.24398923423, :precision => 5) # => 302.24399%
181 181 # number_to_percentage(1000, :locale => :fr) # => 1 000,000%
182 182 # number_to_percentage("98a") # => 98a%
  183 + # number_to_percentage(100, :format => "%n %") # => 100 %
183 184 #
184 185 # number_to_percentage("98a", :raise => true) # => InvalidNumberError
185 186 def number_to_percentage(number, options = {})
@@ -187,19 +188,20 @@ def number_to_percentage(number, options = {})
187 188
188 189 options.symbolize_keys!
189 190
190   - defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
191   - percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :default => {})
192   - defaults = defaults.merge(percentage)
  191 + defaults = defaults_translations(options[:locale]).merge(translations_for('percentage', options[:locale]))
193 192
194 193 options = options.reverse_merge(defaults)
195 194
  195 + format = options[:format] || "%n%"
  196 +
196 197 begin
197   - "#{number_with_precision(number, options.merge(:raise => true))}%".html_safe
  198 + value = number_with_precision(number, options.merge(:raise => true))
  199 + format.gsub(/%n/, value).html_safe
198 200 rescue InvalidNumberError => e
199 201 if options[:raise]
200 202 raise
201 203 else
202   - e.number.to_s.html_safe? ? "#{e.number}%".html_safe : "#{e.number}%"
  204 + e.number.to_s.html_safe? ? format.gsub(/%n/, e.number).html_safe : format.gsub(/%n/, e.number)
203 205 end
204 206 end
205 207 end
@@ -231,23 +233,15 @@ def number_to_percentage(number, options = {})
231 233 def number_with_delimiter(number, options = {})
232 234 options.symbolize_keys!
233 235
234   - begin
235   - Float(number)
236   - rescue ArgumentError, TypeError
237   - if options[:raise]
238   - raise InvalidNumberError, number
239   - else
240   - return number
241   - end
  236 + parse_float_number(number, options[:raise]) do
  237 + return number
242 238 end
243 239
244   - defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
245   - options = options.reverse_merge(defaults)
  240 + options = options.reverse_merge(defaults_translations(options[:locale]))
246 241
247 242 parts = number.to_s.to_str.split('.')
248 243 parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
249 244 parts.join(options[:separator]).html_safe
250   -
251 245 end
252 246
253 247 # Formats a +number+ with the specified level of <tt>:precision</tt> (e.g., 112.32 has a precision
@@ -264,6 +258,7 @@ def number_with_delimiter(number, options = {})
264 258 # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
265 259 # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator
266 260 # (defaults to +false+).
  261 + # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
267 262 #
268 263 # ==== Examples
269 264 # number_with_precision(111.2345) # => 111.235
@@ -284,19 +279,11 @@ def number_with_delimiter(number, options = {})
284 279 def number_with_precision(number, options = {})
285 280 options.symbolize_keys!
286 281
287   - number = begin
288   - Float(number)
289   - rescue ArgumentError, TypeError
290   - if options[:raise]
291   - raise InvalidNumberError, number
292   - else
293   - return number
294   - end
  282 + number = parse_float_number(number, options[:raise]) do
  283 + return number
295 284 end
296 285
297   - defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
298   - precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale], :default => {})
299   - defaults = defaults.merge(precision_defaults)
  286 + defaults = defaults_translations(options[:locale]).merge(translations_for('precision', options[:locale]))
300 287
301 288 options = options.reverse_merge(defaults) # Allow the user to unset default values: Eg.: :significant => false
302 289 precision = options.delete :precision
@@ -323,7 +310,6 @@ def number_with_precision(number, options = {})
323 310 else
324 311 formatted_number
325 312 end
326   -
327 313 end
328 314
329 315 STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb].freeze
@@ -343,6 +329,7 @@ def number_with_precision(number, options = {})
343 329 # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
344 330 # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +true+)
345 331 # * <tt>:prefix</tt> - If +:si+ formats the number using the SI prefix (defaults to :binary)
  332 + # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
346 333 # ==== Examples
347 334 # number_to_human_size(123) # => 123 Bytes
348 335 # number_to_human_size(1234) # => 1.21 KB
@@ -361,19 +348,11 @@ def number_with_precision(number, options = {})
361 348 def number_to_human_size(number, options = {})
362 349 options.symbolize_keys!
363 350
364   - number = begin
365   - Float(number)
366   - rescue ArgumentError, TypeError
367   - if options[:raise]
368   - raise InvalidNumberError, number
369   - else
370   - return number
371   - end
  351 + number = parse_float_number(number, options[:raise]) do
  352 + return number
372 353 end
373 354
374   - defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
375   - human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
376   - defaults = defaults.merge(human)
  355 + defaults = defaults_translations(options[:locale]).merge(translations_for('human', options[:locale]))
377 356
378 357 options = options.reverse_merge(defaults)
379 358 #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
@@ -424,6 +403,7 @@ def number_to_human_size(number, options = {})
424 403 # * *integers*: <tt>:unit</tt>, <tt>:ten</tt>, <tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>, <tt>:billion</tt>, <tt>:trillion</tt>, <tt>:quadrillion</tt>
425 404 # * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>, <tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>, <tt>:pico</tt>, <tt>:femto</tt>
426 405 # * <tt>:format</tt> - Sets the format of the output string (defaults to "%n %u"). The field types are:
  406 + # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
427 407 #
428 408 # %u The quantifier (ex.: 'thousand')
429 409 # %n The number
@@ -480,19 +460,11 @@ def number_to_human_size(number, options = {})
480 460 def number_to_human(number, options = {})
481 461 options.symbolize_keys!
482 462
483   - number = begin
484   - Float(number)
485   - rescue ArgumentError, TypeError
486   - if options[:raise]
487   - raise InvalidNumberError, number
488   - else
489   - return number
490   - end
  463 + number = parse_float_number(number, options[:raise]) do
  464 + return number
491 465 end
492 466
493   - defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
494   - human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
495   - defaults = defaults.merge(human)
  467 + defaults = defaults_translations(options[:locale]).merge(translations_for('human', options[:locale]))
496 468
497 469 options = options.reverse_merge(defaults)
498 470 #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
@@ -530,6 +502,25 @@ def number_to_human(number, options = {})
530 502 decimal_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).strip.html_safe
531 503 end
532 504
  505 + private
  506 +
  507 + def defaults_translations(locale)
  508 + I18n.translate(:'number.format', :locale => locale, :default => {})
  509 + end
  510 +
  511 + def translations_for(namespace, locale)
  512 + I18n.translate(:"number.#{namespace}.format", :locale => locale, :default => {})
  513 + end
  514 +
  515 + def parse_float_number(number, raise_error)
  516 + Float(number)
  517 + rescue ArgumentError, TypeError
  518 + if raise_error
  519 + raise InvalidNumberError, number
  520 + else
  521 + yield
  522 + end
  523 + end
533 524 end
534 525 end
535 526 end
22 actionpack/lib/action_view/helpers/url_helper.rb
@@ -327,7 +327,7 @@ def button_to(name, options = {}, html_options = {})
327 327
328 328 method_tag = ''
329 329 if (method = html_options.delete('method')) && %w{put delete}.include?(method.to_s)
330   - method_tag = tag('input', :type => 'hidden', :name => '_method', :value => method.to_s)
  330 + method_tag = method_tag(method)
331 331 end
332 332
333 333 form_method = method.to_s == 'get' ? 'get' : 'post'
@@ -336,10 +336,7 @@ def button_to(name, options = {}, html_options = {})
336 336
337 337 remote = html_options.delete('remote')
338 338
339   - request_token_tag = ''
340   - if form_method == 'post' && protect_against_forgery?
341   - request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
342   - end
  339 + request_token_tag = form_method == 'post' ? token_tag : ''
343 340
344 341 url = options.is_a?(String) ? options : self.url_for(options)
345 342 name ||= url
@@ -476,7 +473,7 @@ def link_to_if(condition, name, options = {}, html_options = {}, &block)
476 473 # string given as the value.
477 474 # * <tt>:subject</tt> - Preset the subject line of the email.
478 475 # * <tt>:body</tt> - Preset the body of the email.
479   - # * <tt>:cc</tt> - Carbon Copy addition recipients on the email.
  476 + # * <tt>:cc</tt> - Carbon Copy additional recipients on the email.
480 477 # * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email.
481 478 #
482 479 # ==== Examples
@@ -670,6 +667,19 @@ def convert_boolean_attributes!(html_options, bool_attrs)
670 667 bool_attrs.each { |x| html_options[x] = x if html_options.delete(x) }
671 668 html_options
672 669 end
  670 +
  671 + def token_tag(token=nil)
  672 + if token == false || !protect_against_forgery?
  673 + ''
  674 + else
  675 + token ||= form_authenticity_token
  676 + tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => token)
  677 + end
  678 + end
  679 +
  680 + def method_tag(method)
  681 + tag('input', :type => 'hidden', :name => '_method', :value => method.to_s)
  682 + end
673 683 end
674 684 end
675 685 end
1  actionpack/lib/action_view/locale/en.yml
@@ -37,6 +37,7 @@
37 37 # precision:
38 38 # significant: false
39 39 # strip_insignificant_zeros: false
  40 + format: "%n%"
40 41
41 42 # Used in number_to_precision()
42 43 precision:
5 actionpack/lib/action_view/template.rb
@@ -288,7 +288,7 @@ def #{method_name}(local_assigns, output_buffer)
288 288 logger.debug "Backtrace: #{e.backtrace.join("\n")}"
289 289 end
290 290
291   - raise ActionView::Template::Error.new(self, {}, e)
  291 + raise ActionView::Template::Error.new(self, e)
292 292 end
293 293 end
294 294
@@ -297,13 +297,12 @@ def handle_render_error(view, e) #:nodoc:
297 297 e.sub_template_of(self)
298 298 raise e
299 299 else
300   - assigns = view.respond_to?(:assigns) ? view.assigns : {}
301 300 template = self
302 301 unless template.source
303 302 template = refresh(view)
304 303 template.encode!
305 304 end
306   - raise Template::Error.new(template, assigns, e)
  305 + raise Template::Error.new(template, e)
307 306 end
308 307 end
309 308
4 actionpack/lib/action_view/template/error.rb
@@ -55,9 +55,9 @@ class Error < ActionViewError #:nodoc:
55 55
56 56 attr_reader :original_exception, :backtrace
57 57
58   - def initialize(template, assigns, original_exception)
  58 + def initialize(template, original_exception)
59 59 super(original_exception.message)
60   - @template, @assigns, @original_exception = template, assigns.dup, original_exception
  60 + @template, @original_exception = template, original_exception
61 61 @sub_templates = nil
62 62 @backtrace = original_exception.backtrace
63 63 end
18 actionpack/test/controller/addresses_render_test.rb
@@ -3,16 +3,18 @@
3 3 require 'controller/fake_controllers'
4 4
5 5 class Address
6   - def Address.count(conditions = nil, join = nil)
7   - nil
8   - end
  6 + class << self
  7 + def count(conditions = nil, join = nil)
  8 + nil
  9 + end
9 10
10   - def Address.find_all(arg1, arg2, arg3, arg4)
11   - []
12   - end
  11 + def find_all(arg1, arg2, arg3, arg4)
  12 + []
  13 + end
13 14
14   - def self.find(*args)
15   - []
  15 + def find(*args)
  16 + []
  17 + end
16 18 end
17 19 end
18 20
6 actionpack/test/controller/base_test.rb
@@ -93,6 +93,12 @@ def setup
93 93 Submodule::ContainedNonEmptyController.new]
94 94 end
95 95
  96 + def test_performed?
  97 + assert !@empty.performed?
  98 + @empty.response_body = ["sweet"]
  99 + assert @empty.performed?
  100 + end
  101 +
96 102 def test_action_methods
97 103 @empty_controllers.each do |c|
98 104 assert_equal Set.new, c.class.action_methods, "#{c.controller_path} should be empty!"
3  actionpack/test/controller/force_ssl_test.rb
@@ -39,10 +39,8 @@ def use_flash
39 39 @flashy = flash["that"]
40 40 render :inline => "hello"
41 41 end
42   -
43 42 end
44 43
45   -
46 44 class ForceSSLControllerLevelTest < ActionController::TestCase
47 45 tests ForceSSLControllerLevel
48 46
@@ -135,5 +133,4 @@ def test_cheeseburger_redirects_to_https
135 133 assert_equal "hello", assigns["flash_copy"]["that"]
136 134 assert_equal "hello", assigns["flashy"]
137 135 end
138   -
139 136 end
4 actionpack/test/controller/rescue_test.rb
@@ -137,11 +137,11 @@ def missing_template
137 137 end
138 138
139 139 def io_error_in_view
140   - raise ActionView::TemplateError.new(nil, {}, IOError.new('this is io error'))
  140 + raise ActionView::TemplateError.new(nil, IOError.new('this is io error'))
141 141 end
142 142
143 143 def zero_division_error_in_view
144   - raise ActionView::TemplateError.new(nil, {}, ZeroDivisionError.new('this is zero division error'))
  144 + raise ActionView::TemplateError.new(nil, ZeroDivisionError.new('this is zero division error'))
145 145 end
146 146
147 147 protected
15 actionpack/test/controller/routing_test.rb
@@ -1327,7 +1327,20 @@ def test_route_constraints_with_supported_options_must_not_error
1327 1327 end
1328 1328 end
1329 1329 end
1330   -
  1330 +
  1331 + def test_route_with_subdomain_and_constraints_must_receive_params
  1332 + name_param = nil
  1333 + set.draw do
  1334 + match 'page/:name' => 'pages#show', :constraints => lambda {|request|
  1335 + name_param = request.params[:name]
  1336 + return true
  1337 + }
  1338 + end
  1339 + assert_equal({:controller => 'pages', :action => 'show', :name => 'mypage'},
  1340 + set.recognize_path('http://subdomain.example.org/page/mypage'))
  1341 + assert_equal(name_param, 'mypage')
  1342 + end
  1343 +
1331 1344 def test_route_requirement_recognize_with_ignore_case
1332 1345 set.draw do
1333 1346 match 'page/:name' => 'pages#show',
2  actionpack/test/dispatch/debug_exceptions_test.rb
@@ -34,7 +34,7 @@ def call(env)
34 34 when "/unprocessable_entity"
35 35 raise ActionController::InvalidAuthenticityToken
36 36 when "/not_found_original_exception"
37   - raise ActionView::Template::Error.new('template', {}, AbstractController::ActionNotFound.new)
  37 + raise ActionView::Template::Error.new('template', AbstractController::ActionNotFound.new)
38 38 else
39 39 raise "puke!"
40 40 end
2  actionpack/test/dispatch/show_exceptions_test.rb
@@ -11,7 +11,7 @@ def call(env)
11 11 when "/method_not_allowed"
12 12 raise ActionController::MethodNotAllowed
13 13 when "/not_found_original_exception"
14   - raise ActionView::Template::Error.new('template', {}, AbstractController::ActionNotFound.new)
  14 + raise ActionView::Template::Error.new('template', AbstractController::ActionNotFound.new)
15 15 else
16 16 raise "puke!"
17 17 end
2  actionpack/test/template/html-scanner/sanitizer_test.rb
@@ -56,7 +56,6 @@ def test_sanitize_script
56 56 assert_sanitized "a b c<script language=\"Javascript\">blah blah blah</script>d e f", "a b cd e f"
57 57 end
58 58
59   - # TODO: Clean up
60 59 def test_sanitize_js_handlers
61 60 raw = %{onthis="do that" <a href="#" onclick="hello" name="foo" onbogus="remove me">hello</a>}
62 61 assert_sanitized raw, %{onthis="do that" <a name="foo" href="#">hello</a>}
@@ -215,7 +214,6 @@ def test_should_not_fall_for_ridiculous_hack
215 214 assert_sanitized img_hack, "<img>"
216 215 end
217 216
218   - # TODO: Clean up
219 217 def test_should_sanitize_attributes
220 218 assert_sanitized %(<SPAN title="'><script>alert()</script>">blah</SPAN>), %(<span title="'&gt;&lt;script&gt;alert()&lt;/script&gt;">blah</span>)
221 219 end
1  actionpack/test/template/number_helper_test.rb
@@ -57,6 +57,7 @@ def test_number_to_percentage
57 57 assert_equal("1000.000%", number_to_percentage("1000"))
58 58 assert_equal("123.4%", number_to_percentage(123.400, :precision => 3, :strip_insignificant_zeros => true))
59 59 assert_equal("1.000,000%", number_to_percentage(1000, :delimiter => '.', :separator => ','))
  60 + assert_equal("1000.000 %", number_to_percentage(1000, :format => "%n %"))
60 61 end
61 62
62 63 def test_number_with_delimiter
4 actionpack/test/template/template_error_test.rb
@@ -2,12 +2,12 @@
2 2
3 3 class TemplateErrorTest < ActiveSupport::TestCase
4 4 def test_provides_original_message
5   - error = ActionView::Template::Error.new("test", {}, Exception.new("original"))
  5 + error = ActionView::Template::Error.new("test", Exception.new("original"))
6 6 assert_equal "original", error.message
7 7 end
8 8
9 9 def test_provides_useful_inspect
10   - error = ActionView::Template::Error.new("test", {}, Exception.new("original"))
  10 + error = ActionView::Template::Error.new("test", Exception.new("original"))
11 11 assert_equal "#<ActionView::Template::Error: original>", error.inspect
12 12 end
13 13 end
27 actionpack/test/template/url_helper_test.rb
@@ -11,6 +11,9 @@ class UrlHelperTest < ActiveSupport::TestCase
11 11 # In those cases, we'll set up a simple mock
12 12 attr_accessor :controller, :request
13 13
  14 + cattr_accessor :request_forgery
  15 + self.request_forgery = false
  16 +
14 17 routes = ActionDispatch::Routing::RouteSet.new
15 18 routes.draw do
16 19 match "/" => "foo#bar"
@@ -49,11 +52,22 @@ def test_url_for_with_back_and_no_referer
49 52 assert_equal 'javascript:history.back()', url_for(:back)
50 53 end
51 54
52   - # todo: missing test cases
  55 + # TODO: missing test cases
53 56 def test_button_to_with_straight_url
54 57 assert_dom_equal "<form method=\"post\" action=\"http://www.example.com\" class=\"button_to\"><div><input type=\"submit\" value=\"Hello\" /></div></form>", button_to("Hello", "http://www.example.com")
55 58 end
56 59
  60 + def test_button_to_with_straight_url_and_request_forgery
  61 + self.request_forgery = true
  62 +
  63 + assert_dom_equal(
  64 + %{<form method="post" action="http://www.example.com" class="button_to"><div><input type="submit" value="Hello" /><input name="form_token" type="hidden" value="secret" /></div></form>},
  65 + button_to("Hello", "http://www.example.com")
  66 + )
  67 + ensure
  68 + self.request_forgery = false
  69 + end
  70 +
57 71 def test_button_to_with_form_class
58 72 assert_dom_equal "<form method=\"post\" action=\"http://www.example.com\" class=\"custom-class\"><div><input type=\"submit\" value=\"Hello\" /></div></form>", button_to("Hello", "http://www.example.com", :form_class => 'custom-class')
59 73 end
@@ -435,9 +449,16 @@ def test_mail_to_returns_html_safe_string
435 449 assert mail_to("me@domain.com", "My email", :encode => "hex").html_safe?
436 450 end
437 451
438   - # TODO: button_to looks at this ... why?
439 452 def protect_against_forgery?
440   - false
  453 + self.request_forgery
  454 + end
  455 +
  456 + def form_authenticity_token
  457 + "secret"
  458 + end
  459 +
  460 + def request_forgery_protection_token
  461 + "form_token"
441 462 end
442 463
443 464 private
4 activemodel/lib/active_model/attribute_methods.rb
@@ -325,14 +325,14 @@ def initialize(options = {})
325 325 end
326 326
327 327 @prefix, @suffix = options[:prefix] || '', options[:suffix] || ''
328   - @regex = /^(#{Regexp.escape(@prefix)})(.+?)(#{Regexp.escape(@suffix)})$/
  328 + @regex = /^(?:#{Regexp.escape(@prefix)})(.*)(?:#{Regexp.escape(@suffix)})$/
329 329 @method_missing_target = "#{@prefix}attribute#{@suffix}"
330 330 @method_name = "#{prefix}%s#{suffix}"
331 331 end
332 332
333 333 def match(method_name)
334 334 if @regex =~ method_name
335   - AttributeMethodMatch.new(method_missing_target, $2, method_name)
  335 + AttributeMethodMatch.new(method_missing_target, $1, method_name)
336 336 else
337 337 nil
338 338 end
7 activemodel/lib/active_model/errors.rb
@@ -4,12 +4,11 @@
4 4 require 'active_support/core_ext/string/inflections'
5 5 require 'active_support/core_ext/object/blank'
6 6 require 'active_support/core_ext/hash/reverse_merge'
7   -require 'active_support/ordered_hash'
8 7
9 8 module ActiveModel
10 9 # == Active Model Errors
11 10 #
12   - # Provides a modified +OrderedHash+ that you can include in your object
  11 + # Provides a modified +Hash+ that you can include in your object
13 12 # for handling error messages and interacting with Action Pack helpers.
14 13 #
15 14 # A minimal implementation could be:
@@ -75,7 +74,7 @@ class Errors
75 74 # end
76 75 def initialize(base)
77 76 @base = base
78   - @messages = ActiveSupport::OrderedHash.new
  77 + @messages = {}
79 78 end
80 79
81 80 def initialize_dup(other)
@@ -206,7 +205,7 @@ def to_xml(options={})
206 205 to_a.to_xml options.reverse_merge(:root => "errors", :skip_types => true)
207 206 end
208 207
209   - # Returns an ActiveSupport::OrderedHash that can be used as the JSON representation for this object.
  208 + # Returns an Hash that can be used as the JSON representation for this object.
210 209 def as_json(options=nil)
211 210 to_hash
212 211 end
2  activemodel/lib/active_model/validations.rb
@@ -33,7 +33,7 @@ module ActiveModel
33 33 # person.first_name = 'zoolander'
34 34 # person.valid? # => false
35 35 # person.invalid? # => true
36   - # person.errors # => #<OrderedHash {:first_name=>["starts with z."]}>
  36 + # person.errors # => #<Hash {:first_name=>["starts with z."]}>
37 37 #
38 38 # Note that <tt>ActiveModel::Validations</tt> automatically adds an +errors+ method
39 39 # to your instances initialized with a new <tt>ActiveModel::Errors</tt> object, so
2  activemodel/test/cases/errors_test.rb
@@ -154,7 +154,7 @@ def test_has_key?
154 154 test 'to_hash should return an ordered hash' do
155 155 person = Person.new
156 156 person.errors.add(:name, "can not be blank")
157   - assert_instance_of ActiveSupport::OrderedHash, person.errors.to_hash
  157 + assert_instance_of ::Hash, person.errors.to_hash
158 158 end
159 159
160 160 test 'full_messages should return an array of error messages, with the attribute name included' do
4 activemodel/test/cases/serializers/json_serialization_test.rb
@@ -130,13 +130,13 @@ def @contact.favorite_quote; "Constraints are liberating"; end
130 130 assert_match %r{"favorite_quote":"Constraints are liberating"}, methods_json
131 131 end
132 132
133   - test "should return OrderedHash for errors" do
  133 + test "should return Hash for errors" do
134 134 contact = Contact.new
135 135 contact.errors.add :name, "can't be blank"
136 136 contact.errors.add :name, "is too short (minimum is 2 characters)"
137 137 contact.errors.add :age, "must be 16 or over"
138 138
139   - hash = ActiveSupport::OrderedHash.new
  139 + hash = {}
140 140 hash[:name] = ["can't be blank", "is too short (minimum is 2 characters)"]
141 141 hash[:age] = ["must be 16 or over"]
142 142 assert_equal hash.to_json, contact.errors.to_json
2  activemodel/test/cases/validations_test.rb
@@ -181,7 +181,7 @@ def test_errors_conversions
181 181 assert_match %r{<error>Title can't be blank</error>}, xml
182 182 assert_match %r{<error>Content can't be blank</error>}, xml
183 183
184   - hash = ActiveSupport::OrderedHash.new
  184 + hash = {}
185 185 hash[:title] = ["can't be blank"]
186 186 hash[:content] = ["can't be blank"]
187 187 assert_equal t.errors.to_json, hash.to_json
29 activerecord/CHANGELOG.md
Source Rendered
@@ -72,6 +72,33 @@
72 72
73 73 ## Rails 3.2.0 (unreleased) ##
74 74
  75 +* Added a `with_lock` method to ActiveRecord objects, which starts
  76 + a transaction, locks the object (pessimistically) and yields to the block.
  77 + The method takes one (optional) parameter and passes it to `lock!`.
  78 +
  79 + Before:
  80 +
  81 + class Order < ActiveRecord::Base
  82 + def cancel!
  83 + transaction do
  84 + lock!
  85 + # ... cancelling logic
  86 + end
  87 + end
  88 + end
  89 +
  90 + After:
  91 +
  92 + class Order < ActiveRecord::Base
  93 + def cancel!
  94 + with_lock do
  95 + # ... cancelling logic
  96 + end
  97 + end
  98 + end
  99 +
  100 + *Olek Janiszewski*
  101 +
75 102 * 'on' and 'ON' boolean columns values are type casted to true
76 103 *Santiago Pastorino*
77 104
@@ -82,7 +109,7 @@
82 109 Example:
83 110 rake db:migrate SCOPE=blog
84 111
85   - *Piotr Sarnacki*
  112 + *Piotr Sarnacki*
86 113
87 114 * Migrations copied from engines are now scoped with engine's name,
88 115 for example 01_create_posts.blog.rb. *Piotr Sarnacki*
3  activerecord/lib/active_record/attribute_methods.rb
... ... @@ -1,6 +1,5 @@
1 1 require 'active_support/core_ext/enumerable'
2 2 require 'active_support/deprecation'
3   -require 'thread'
4 3
5 4 module ActiveRecord
6 5 # = Active Record Attribute Methods
@@ -38,8 +37,6 @@ module ClassMethods
38 37 def define_attribute_methods
39 38 # Use a mutex; we don't want two thread simaltaneously trying to define
40 39 # attribute methods.
41   - @attribute_methods_mutex ||= Mutex.new
42   -
43 40 @attribute_methods_mutex.synchronize do
44 41 return if attribute_methods_generated?
45 42 superclass.define_attribute_methods unless self == base_class
2  activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
@@ -71,7 +71,7 @@ def type_cast(value, column)
71 71 when Date, Time then quoted_date(value)
72 72 when Symbol then value.to_s
73 73 else
74   - YAML.dump(value)
  74 + raise TypeError, "can't cast #{value.class} to #{column.type}"
75 75 end
76 76 end
77 77
16 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -171,15 +171,15 @@ def simplified_type(field_type)
171 171
172 172 # Extracts the value from a PostgreSQL column default definition.
173 173 def self.extract_value_from_default(default)
  174 + # This is a performance optimization for Ruby 1.9.2 in development.
  175 + # If the value is nil, we return nil straight away without checking
  176 + # the regular expressions. If we check each regular expression,
  177 + # Regexp#=== will call NilClass#to_str, which will trigger
  178 + # method_missing (defined by whiny nil in ActiveSupport) which
  179 + # makes this method very very slow.
  180 + return default unless default
  181 +
174 182 case default
175   - # This is a performance optimization for Ruby 1.9.2 in development.
176   - # If the value is nil, we return nil straight away without checking
177   - # the regular expressions. If we check each regular expression,
178   - # Regexp#=== will call NilClass#to_str, which will trigger
179   - # method_missing (defined by whiny nil in ActiveSupport) which
180   - # makes this method very very slow.
181   - when NilClass
182   - nil
183 183 # Numeric types
184 184 when /\A\(?(-?\d+(\.\d*)?\)?)\z/
185 185 $1
39 activerecord/lib/active_record/core.rb
... ... @@ -1,4 +1,5 @@
1 1 require 'active_support/concern'
  2 +require 'thread'
2 3
3 4 module ActiveRecord
4 5 module Core
@@ -80,6 +81,8 @@ def inherited(child_class) #:nodoc:
80 81 end
81 82
82 83 def initialize_generated_modules
  84 + @attribute_methods_mutex = Mutex.new
  85 +
83 86 # force attribute methods to be higher in inheritance hierarchy than other generated methods
84 87 generated_attribute_methods
85 88 generated_feature_methods
@@ -152,16 +155,8 @@ def relation #:nodoc:
152 155 # User.new({ :first_name => 'Jamie', :is_admin => true }, :without_protection => true)
153 156 def initialize(attributes = nil, options = {})
154 157 @attributes = self.class.initialize_attributes(self.class.column_defaults.dup)
155   - @association_cache = {}
156   - @aggregation_cache = {}
157   - @attributes_cache = {}
158   - @new_record = true
159   - @readonly = false
160   - @destroyed = false
161   - @marked_for_destruction = false
162   - @previously_changed = {}
163   - @changed_attributes = {}
164   - @relation = nil
  158 +
  159 + init_internals
165 160
166 161 ensure_proper_type
167 162