Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

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
Prasath V Ram ask4prasath closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 7, 2012
  1. karevn

    Fix: when using subdomains and constraints, request params were not p…

    karevn authored prasath committed
    …assed to constraints callback
  2. Ravil Bayramgalin

    Update time zone offset information

    brainopia authored prasath committed
  3. Guillermo Iguaran

    Update Release Notes: sprockets-rails section should be inside of Act…

    guilleiguaran authored prasath committed
    …ionPack section
  4. Guillermo Iguaran

    Adding Action Mailer section to 3.2 release notes

    guilleiguaran authored prasath committed
  5. Rafael Mendonça França

    Refactor button_to helper to use token_tag method

    rafaelfranca authored prasath committed
  6. Rafael Mendonça França

    Extract method_tag

    rafaelfranca authored prasath committed
  7. Vasiliy Ermolovich

    remove ruby 1.8 related code

    nashby authored prasath committed
  8. Olek Janiszewski

    Add ActiveRecord::Base#with_lock

    exviva authored prasath committed
    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
  9. Sergey Nartimov

    refactor RAILS_CACHE deprecation

    lest authored prasath committed
    that was introduced in 6f8159c
  10. Refactored class methods on address render test

    prasath authored
  11. Vijay Dev

    revise wording [ci skip]

    vijaydev authored prasath committed
  12. Fujimura Daisuke

    update release note: timestamps is non-null as default

    fujimura authored prasath committed
  13. Simon Baird

    Fix small typo in mail_to docs in url_helper.rb

    simonbaird authored prasath committed
  14. Toshinori Kajihara

    Convert URI.parser.parse to URI.parse, and remove ruby 1.8.x code.

    kennyj authored prasath committed
  15. Vijay Dev

    select doesn't take multiple arguments - fixes #4539 [ci skip]

    vijaydev authored prasath committed
    Also, fixed the bit about returning AM::MissingAttributeError. This
    seems to be fixed earlier in 3-2-stable only.
  16. Vijay Dev

    revising release notes [ci skip]

    vijaydev authored prasath committed
  17. Manu J

    Fix for log tailer when the log file doesn't exist.

    j-manu authored prasath committed
  18. Aaron Patterson

    do not do reverse lookups on incoming requests for webrick. fixes #4542

    tenderlove authored prasath committed
  19. Trotter Cashion

    Fix documentation bug in Rails::Engine

    trotter authored prasath committed
  20. Aaron Patterson

    move tagged logging to a module, stop proxying every method call

    tenderlove authored prasath committed
  21. Aaron Patterson

    avoid useless is_a checks

    tenderlove authored prasath committed
  22. Aaron Patterson

    remove unused captures

    tenderlove authored prasath committed
  23. Carlos Antonio da Silva

    Use performed? instead of checking for response_body

    carlosantoniodasilva authored prasath committed
    * Check for performed? instead of response_body
    * Change performed? to return a boolean
    * Refactor AC::Metal#response_body= to reuse variable
  24. José Valim

    Do not deprecate performed.

    josevalim authored prasath committed
  25. Vijay Dev

    update the getting_started guide code [ci skip]

    vijaydev authored prasath committed
  26. Vijay Dev

    document AR::Base#with_lock in release notes [ci skip]

    vijaydev authored prasath committed
  27. Vijay Dev

    fix duplicate ids for the headers [ci skip]

    vijaydev authored prasath committed
  28. Vijay Dev

    add uglifier version info in the 'what to update' section

    vijaydev authored prasath committed
  29. Vijay Dev

    update release notes [ci skip]

    vijaydev authored prasath committed
  30. Stephen Celis

    Don't type-cast unknown types to YAML.

    stephencelis authored prasath committed
  31. Aaron Patterson

    just use an alias. The target method is public, so make this one public

    tenderlove authored prasath committed
    too.
  32. Aaron Patterson

    adding tests for previous_changes hash

    tenderlove authored prasath committed
  33. Aaron Patterson

    push ivar initialization down to a common method

    tenderlove authored prasath committed
  34. Added format to percentage

    Rodrigo Flores authored prasath committed
  35. Aaron Patterson

    Revert "just use an alias. The target method is public, so make this …

    tenderlove authored prasath committed
    …one public"
    
    This reverts commit be7d224.
  36. Tomasz Zurkowski

    Fix indentation in code example of Delegation

    doriath authored prasath committed
  37. document `:raise` option support for several helpers [ci skip]

    Jonathan Roes authored prasath committed
  38. Rafael Mendonça França

    No need to check html_safe? twice

    rafaelfranca authored prasath committed
  39. Jon Leighton

    Fix another race condition.

    jonleighton authored prasath committed
    From 2c667f6.
    
    Thanks @pwnall for the heads-up.
  40. Ravil Bayramgalin

    Removed unused assigns from ActionView::Template::Error

    brainopia authored prasath committed
    They existed since initial rails commit by DHH but lost use a long time
    ago
  41. Toshinori Kajihara

    Bump mail

    kennyj authored prasath committed
  42. Rafael Mendonça França

    Remove code duplication

    rafaelfranca authored prasath committed
  43. Rafael Mendonça França

    Refactor translations retrieval

    rafaelfranca authored prasath committed
  44. replacing ordered hash to ruby hash

    prasath authored
This page is out of date. Refresh to see the latest.
Showing with 485 additions and 307 deletions.
  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
View
@@ -17,5 +17,5 @@ Gem::Specification.new do |s|
s.requirements << 'none'
s.add_dependency('actionpack', version)
- s.add_dependency('mail', '~> 2.4.0')
+ s.add_dependency('mail', '~> 2.4.1')
end
5 actionpack/CHANGELOG.md
View
@@ -1,4 +1,7 @@
## Rails 4.0.0 (unreleased) ##
+
+* Add `:format` option to number_to_percentage *Rodrigo Flores*
+
* Add `config.action_view.logger` to configure logger for ActionView. *Rafael França*
* Deprecated ActionController::Integration in favour of ActionDispatch::Integration
@@ -33,8 +36,6 @@
* Deprecate method_missing handling for not found actions, use action_missing instead. *Carlos Antonio da Silva*
-* Deprecate ActionController#performed?, check for response_body presence instead. *Carlos Antonio da Silva*
-
* Deprecate ActionController#rescue_action, ActionController#initialize_template_class, and ActionController#assign_shortcuts.
These methods were not being used internally anymore and are going to be removed in Rails 4. *Carlos Antonio da Silva*
10 actionpack/lib/action_controller/metal.rb
View
@@ -181,9 +181,13 @@ def status=(status)
@_status = Rack::Utils.status_code(status)
end
- def response_body=(val)
- body = (val.nil? || val.respond_to?(:each)) ? val : [val]
- super body
+ def response_body=(body)
+ body = [body] unless body.nil? || body.respond_to?(:each)
+ super
+ end
+
+ def performed?
+ !!response_body
end
def dispatch(name, request) #:nodoc:
2  actionpack/lib/action_controller/metal/implicit_render.rb
View
@@ -2,7 +2,7 @@ module ActionController
module ImplicitRender
def send_action(method, *args)
ret = super
- default_render unless response_body
+ default_render unless performed?
ret
end
3  actionpack/lib/action_dispatch/routing/route_set.rb
View
@@ -579,7 +579,8 @@ def recognize_path(path, environment = {})
params[key] = URI.parser.unescape(value)
end
end
-
+ old_params = env[::ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
+ env[::ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] = (old_params || {}).merge(params)
dispatcher = route.app
while dispatcher.is_a?(Mapper::Constraints) && dispatcher.matches?(env) do
dispatcher = dispatcher.app
11 actionpack/lib/action_view/helpers/form_tag_helper.rb
View
@@ -627,7 +627,7 @@ def extra_tags_for_form(html_options)
token_tag(authenticity_token)
else
html_options["method"] = "post"
- tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag(authenticity_token)
+ method_tag(method) + token_tag(authenticity_token)
end
tags = utf8_enforcer_tag << method_tag
@@ -646,15 +646,6 @@ def form_tag_in_block(html_options, &block)
output.safe_concat("</form>")
end
- def token_tag(token)
- if token == false || !protect_against_forgery?
- ''
- else
- token ||= form_authenticity_token
- tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => token)
- end
- end
-
# see http://www.w3.org/TR/html4/types.html#type-name
def sanitize_to_id(name)
name.to_s.gsub(']','').gsub(/[^-a-zA-Z0-9:.]/, "_")
99 actionpack/lib/action_view/helpers/number_helper.rb
View
@@ -125,11 +125,10 @@ def number_to_currency(number, options = {})
options.symbolize_keys!
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
- currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
+ currency = translations_for('currency', options[:locale])
currency[:negative_format] ||= "-" + currency[:format] if currency[:format]
- defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency)
+ defaults = DEFAULT_CURRENCY_VALUES.merge(defaults_translations(options[:locale])).merge!(currency)
defaults[:negative_format] = "-" + options[:format] if options[:format]
options = defaults.merge!(options)
@@ -152,7 +151,6 @@ def number_to_currency(number, options = {})
e.number.to_s.html_safe? ? formatted_number.html_safe : formatted_number
end
end
-
end
# 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 = {})
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
# * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator
# (defaults to +false+).
+ # * <tt>:format</tt> - Specifies the format of the percentage string
+ # The number field is <tt>%n</tt> (defaults to "%n%").
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
#
# ==== Examples
@@ -180,6 +180,7 @@ def number_to_currency(number, options = {})
# number_to_percentage(302.24398923423, :precision => 5) # => 302.24399%
# number_to_percentage(1000, :locale => :fr) # => 1 000,000%
# number_to_percentage("98a") # => 98a%
+ # number_to_percentage(100, :format => "%n %") # => 100 %
#
# number_to_percentage("98a", :raise => true) # => InvalidNumberError
def number_to_percentage(number, options = {})
@@ -187,19 +188,20 @@ def number_to_percentage(number, options = {})
options.symbolize_keys!
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
- percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :default => {})
- defaults = defaults.merge(percentage)
+ defaults = defaults_translations(options[:locale]).merge(translations_for('percentage', options[:locale]))
options = options.reverse_merge(defaults)
+ format = options[:format] || "%n%"
+
begin
- "#{number_with_precision(number, options.merge(:raise => true))}%".html_safe
+ value = number_with_precision(number, options.merge(:raise => true))
+ format.gsub(/%n/, value).html_safe
rescue InvalidNumberError => e
if options[:raise]
raise
else
- e.number.to_s.html_safe? ? "#{e.number}%".html_safe : "#{e.number}%"
+ e.number.to_s.html_safe? ? format.gsub(/%n/, e.number).html_safe : format.gsub(/%n/, e.number)
end
end
end
@@ -231,23 +233,15 @@ def number_to_percentage(number, options = {})
def number_with_delimiter(number, options = {})
options.symbolize_keys!
- begin
- Float(number)
- rescue ArgumentError, TypeError
- if options[:raise]
- raise InvalidNumberError, number
- else
- return number
- end
+ parse_float_number(number, options[:raise]) do
+ return number
end
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
- options = options.reverse_merge(defaults)
+ options = options.reverse_merge(defaults_translations(options[:locale]))
parts = number.to_s.to_str.split('.')
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
parts.join(options[:separator]).html_safe
-
end
# 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 = {})
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
# * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator
# (defaults to +false+).
+ # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
#
# ==== Examples
# number_with_precision(111.2345) # => 111.235
@@ -284,19 +279,11 @@ def number_with_delimiter(number, options = {})
def number_with_precision(number, options = {})
options.symbolize_keys!
- number = begin
- Float(number)
- rescue ArgumentError, TypeError
- if options[:raise]
- raise InvalidNumberError, number
- else
- return number
- end
+ number = parse_float_number(number, options[:raise]) do
+ return number
end
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
- precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale], :default => {})
- defaults = defaults.merge(precision_defaults)
+ defaults = defaults_translations(options[:locale]).merge(translations_for('precision', options[:locale]))
options = options.reverse_merge(defaults) # Allow the user to unset default values: Eg.: :significant => false
precision = options.delete :precision
@@ -323,7 +310,6 @@ def number_with_precision(number, options = {})
else
formatted_number
end
-
end
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb].freeze
@@ -343,6 +329,7 @@ def number_with_precision(number, options = {})
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
# * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +true+)
# * <tt>:prefix</tt> - If +:si+ formats the number using the SI prefix (defaults to :binary)
+ # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
# ==== Examples
# number_to_human_size(123) # => 123 Bytes
# number_to_human_size(1234) # => 1.21 KB
@@ -361,19 +348,11 @@ def number_with_precision(number, options = {})
def number_to_human_size(number, options = {})
options.symbolize_keys!
- number = begin
- Float(number)
- rescue ArgumentError, TypeError
- if options[:raise]
- raise InvalidNumberError, number
- else
- return number
- end
+ number = parse_float_number(number, options[:raise]) do
+ return number
end
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
- human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
- defaults = defaults.merge(human)
+ defaults = defaults_translations(options[:locale]).merge(translations_for('human', options[:locale]))
options = options.reverse_merge(defaults)
#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 = {})
# * *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>
# * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>, <tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>, <tt>:pico</tt>, <tt>:femto</tt>
# * <tt>:format</tt> - Sets the format of the output string (defaults to "%n %u"). The field types are:
+ # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
#
# %u The quantifier (ex.: 'thousand')
# %n The number
@@ -480,19 +460,11 @@ def number_to_human_size(number, options = {})
def number_to_human(number, options = {})
options.symbolize_keys!
- number = begin
- Float(number)
- rescue ArgumentError, TypeError
- if options[:raise]
- raise InvalidNumberError, number
- else
- return number
- end
+ number = parse_float_number(number, options[:raise]) do
+ return number
end
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
- human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
- defaults = defaults.merge(human)
+ defaults = defaults_translations(options[:locale]).merge(translations_for('human', options[:locale]))
options = options.reverse_merge(defaults)
#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 = {})
decimal_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).strip.html_safe
end
+ private
+
+ def defaults_translations(locale)
+ I18n.translate(:'number.format', :locale => locale, :default => {})
+ end
+
+ def translations_for(namespace, locale)
+ I18n.translate(:"number.#{namespace}.format", :locale => locale, :default => {})
+ end
+
+ def parse_float_number(number, raise_error)
+ Float(number)
+ rescue ArgumentError, TypeError
+ if raise_error
+ raise InvalidNumberError, number
+ else
+ yield
+ end
+ end
end
end
end
22 actionpack/lib/action_view/helpers/url_helper.rb
View
@@ -327,7 +327,7 @@ def button_to(name, options = {}, html_options = {})
method_tag = ''
if (method = html_options.delete('method')) && %w{put delete}.include?(method.to_s)
- method_tag = tag('input', :type => 'hidden', :name => '_method', :value => method.to_s)
+ method_tag = method_tag(method)
end
form_method = method.to_s == 'get' ? 'get' : 'post'
@@ -336,10 +336,7 @@ def button_to(name, options = {}, html_options = {})
remote = html_options.delete('remote')
- request_token_tag = ''
- if form_method == 'post' && protect_against_forgery?
- request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
- end
+ request_token_tag = form_method == 'post' ? token_tag : ''
url = options.is_a?(String) ? options : self.url_for(options)
name ||= url
@@ -476,7 +473,7 @@ def link_to_if(condition, name, options = {}, html_options = {}, &block)
# string given as the value.
# * <tt>:subject</tt> - Preset the subject line of the email.
# * <tt>:body</tt> - Preset the body of the email.
- # * <tt>:cc</tt> - Carbon Copy addition recipients on the email.
+ # * <tt>:cc</tt> - Carbon Copy additional recipients on the email.
# * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email.
#
# ==== Examples
@@ -670,6 +667,19 @@ def convert_boolean_attributes!(html_options, bool_attrs)
bool_attrs.each { |x| html_options[x] = x if html_options.delete(x) }
html_options
end
+
+ def token_tag(token=nil)
+ if token == false || !protect_against_forgery?
+ ''
+ else
+ token ||= form_authenticity_token
+ tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => token)
+ end
+ end
+
+ def method_tag(method)
+ tag('input', :type => 'hidden', :name => '_method', :value => method.to_s)
+ end
end
end
end
1  actionpack/lib/action_view/locale/en.yml
View
@@ -37,6 +37,7 @@
# precision:
# significant: false
# strip_insignificant_zeros: false
+ format: "%n%"
# Used in number_to_precision()
precision:
5 actionpack/lib/action_view/template.rb
View
@@ -288,7 +288,7 @@ def #{method_name}(local_assigns, output_buffer)
logger.debug "Backtrace: #{e.backtrace.join("\n")}"
end
- raise ActionView::Template::Error.new(self, {}, e)
+ raise ActionView::Template::Error.new(self, e)
end
end
@@ -297,13 +297,12 @@ def handle_render_error(view, e) #:nodoc:
e.sub_template_of(self)
raise e
else
- assigns = view.respond_to?(:assigns) ? view.assigns : {}
template = self
unless template.source
template = refresh(view)
template.encode!
end
- raise Template::Error.new(template, assigns, e)
+ raise Template::Error.new(template, e)
end
end
4 actionpack/lib/action_view/template/error.rb
View
@@ -55,9 +55,9 @@ class Error < ActionViewError #:nodoc:
attr_reader :original_exception, :backtrace
- def initialize(template, assigns, original_exception)
+ def initialize(template, original_exception)
super(original_exception.message)
- @template, @assigns, @original_exception = template, assigns.dup, original_exception
+ @template, @original_exception = template, original_exception
@sub_templates = nil
@backtrace = original_exception.backtrace
end
18 actionpack/test/controller/addresses_render_test.rb
View
@@ -3,16 +3,18 @@
require 'controller/fake_controllers'
class Address
- def Address.count(conditions = nil, join = nil)
- nil
- end
+ class << self
+ def count(conditions = nil, join = nil)
+ nil
+ end
- def Address.find_all(arg1, arg2, arg3, arg4)
- []
- end
+ def find_all(arg1, arg2, arg3, arg4)
+ []
+ end
- def self.find(*args)
- []
+ def find(*args)
+ []
+ end
end
end
6 actionpack/test/controller/base_test.rb
View
@@ -93,6 +93,12 @@ def setup
Submodule::ContainedNonEmptyController.new]
end
+ def test_performed?
+ assert !@empty.performed?
+ @empty.response_body = ["sweet"]
+ assert @empty.performed?
+ end
+
def test_action_methods
@empty_controllers.each do |c|
assert_equal Set.new, c.class.action_methods, "#{c.controller_path} should be empty!"
3  actionpack/test/controller/force_ssl_test.rb
View
@@ -39,10 +39,8 @@ def use_flash
@flashy = flash["that"]
render :inline => "hello"
end
-
end
-
class ForceSSLControllerLevelTest < ActionController::TestCase
tests ForceSSLControllerLevel
@@ -135,5 +133,4 @@ def test_cheeseburger_redirects_to_https
assert_equal "hello", assigns["flash_copy"]["that"]
assert_equal "hello", assigns["flashy"]
end
-
end
4 actionpack/test/controller/rescue_test.rb
View
@@ -137,11 +137,11 @@ def missing_template
end
def io_error_in_view
- raise ActionView::TemplateError.new(nil, {}, IOError.new('this is io error'))
+ raise ActionView::TemplateError.new(nil, IOError.new('this is io error'))
end
def zero_division_error_in_view
- raise ActionView::TemplateError.new(nil, {}, ZeroDivisionError.new('this is zero division error'))
+ raise ActionView::TemplateError.new(nil, ZeroDivisionError.new('this is zero division error'))
end
protected
15 actionpack/test/controller/routing_test.rb
View
@@ -1327,7 +1327,20 @@ def test_route_constraints_with_supported_options_must_not_error
end
end
end
-
+
+ def test_route_with_subdomain_and_constraints_must_receive_params
+ name_param = nil
+ set.draw do
+ match 'page/:name' => 'pages#show', :constraints => lambda {|request|
+ name_param = request.params[:name]
+ return true
+ }
+ end
+ assert_equal({:controller => 'pages', :action => 'show', :name => 'mypage'},
+ set.recognize_path('http://subdomain.example.org/page/mypage'))
+ assert_equal(name_param, 'mypage')
+ end
+
def test_route_requirement_recognize_with_ignore_case
set.draw do
match 'page/:name' => 'pages#show',
2  actionpack/test/dispatch/debug_exceptions_test.rb
View
@@ -34,7 +34,7 @@ def call(env)
when "/unprocessable_entity"
raise ActionController::InvalidAuthenticityToken
when "/not_found_original_exception"
- raise ActionView::Template::Error.new('template', {}, AbstractController::ActionNotFound.new)
+ raise ActionView::Template::Error.new('template', AbstractController::ActionNotFound.new)
else
raise "puke!"
end
2  actionpack/test/dispatch/show_exceptions_test.rb
View
@@ -11,7 +11,7 @@ def call(env)
when "/method_not_allowed"
raise ActionController::MethodNotAllowed
when "/not_found_original_exception"
- raise ActionView::Template::Error.new('template', {}, AbstractController::ActionNotFound.new)
+ raise ActionView::Template::Error.new('template', AbstractController::ActionNotFound.new)
else
raise "puke!"
end
2  actionpack/test/template/html-scanner/sanitizer_test.rb
View
@@ -56,7 +56,6 @@ def test_sanitize_script
assert_sanitized "a b c<script language=\"Javascript\">blah blah blah</script>d e f", "a b cd e f"
end
- # TODO: Clean up
def test_sanitize_js_handlers
raw = %{onthis="do that" <a href="#" onclick="hello" name="foo" onbogus="remove me">hello</a>}
assert_sanitized raw, %{onthis="do that" <a name="foo" href="#">hello</a>}
@@ -215,7 +214,6 @@ def test_should_not_fall_for_ridiculous_hack
assert_sanitized img_hack, "<img>"
end
- # TODO: Clean up
def test_should_sanitize_attributes
assert_sanitized %(<SPAN title="'><script>alert()</script>">blah</SPAN>), %(<span title="'&gt;&lt;script&gt;alert()&lt;/script&gt;">blah</span>)
end
1  actionpack/test/template/number_helper_test.rb
View
@@ -57,6 +57,7 @@ def test_number_to_percentage
assert_equal("1000.000%", number_to_percentage("1000"))
assert_equal("123.4%", number_to_percentage(123.400, :precision => 3, :strip_insignificant_zeros => true))
assert_equal("1.000,000%", number_to_percentage(1000, :delimiter => '.', :separator => ','))
+ assert_equal("1000.000 %", number_to_percentage(1000, :format => "%n %"))
end
def test_number_with_delimiter
4 actionpack/test/template/template_error_test.rb
View
@@ -2,12 +2,12 @@
class TemplateErrorTest < ActiveSupport::TestCase
def test_provides_original_message
- error = ActionView::Template::Error.new("test", {}, Exception.new("original"))
+ error = ActionView::Template::Error.new("test", Exception.new("original"))
assert_equal "original", error.message
end
def test_provides_useful_inspect
- error = ActionView::Template::Error.new("test", {}, Exception.new("original"))
+ error = ActionView::Template::Error.new("test", Exception.new("original"))
assert_equal "#<ActionView::Template::Error: original>", error.inspect
end
end
27 actionpack/test/template/url_helper_test.rb
View
@@ -11,6 +11,9 @@ class UrlHelperTest < ActiveSupport::TestCase
# In those cases, we'll set up a simple mock
attr_accessor :controller, :request
+ cattr_accessor :request_forgery
+ self.request_forgery = false
+
routes = ActionDispatch::Routing::RouteSet.new
routes.draw do
match "/" => "foo#bar"
@@ -49,11 +52,22 @@ def test_url_for_with_back_and_no_referer
assert_equal 'javascript:history.back()', url_for(:back)
end
- # todo: missing test cases
+ # TODO: missing test cases
def test_button_to_with_straight_url
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")
end
+ def test_button_to_with_straight_url_and_request_forgery
+ self.request_forgery = true
+
+ assert_dom_equal(
+ %{<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>},
+ button_to("Hello", "http://www.example.com")
+ )
+ ensure
+ self.request_forgery = false
+ end
+
def test_button_to_with_form_class
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')
end
@@ -435,9 +449,16 @@ def test_mail_to_returns_html_safe_string
assert mail_to("me@domain.com", "My email", :encode => "hex").html_safe?
end
- # TODO: button_to looks at this ... why?
def protect_against_forgery?
- false
+ self.request_forgery
+ end
+
+ def form_authenticity_token
+ "secret"
+ end
+
+ def request_forgery_protection_token
+ "form_token"
end
private
4 activemodel/lib/active_model/attribute_methods.rb
View
@@ -325,14 +325,14 @@ def initialize(options = {})
end
@prefix, @suffix = options[:prefix] || '', options[:suffix] || ''
- @regex = /^(#{Regexp.escape(@prefix)})(.+?)(#{Regexp.escape(@suffix)})$/
+ @regex = /^(?:#{Regexp.escape(@prefix)})(.*)(?:#{Regexp.escape(@suffix)})$/
@method_missing_target = "#{@prefix}attribute#{@suffix}"
@method_name = "#{prefix}%s#{suffix}"
end
def match(method_name)
if @regex =~ method_name
- AttributeMethodMatch.new(method_missing_target, $2, method_name)
+ AttributeMethodMatch.new(method_missing_target, $1, method_name)
else
nil
end
7 activemodel/lib/active_model/errors.rb
View
@@ -4,12 +4,11 @@
require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/hash/reverse_merge'
-require 'active_support/ordered_hash'
module ActiveModel
# == Active Model Errors
#
- # Provides a modified +OrderedHash+ that you can include in your object
+ # Provides a modified +Hash+ that you can include in your object
# for handling error messages and interacting with Action Pack helpers.
#
# A minimal implementation could be:
@@ -75,7 +74,7 @@ class Errors
# end
def initialize(base)
@base = base
- @messages = ActiveSupport::OrderedHash.new
+ @messages = {}
end
def initialize_dup(other)
@@ -206,7 +205,7 @@ def to_xml(options={})
to_a.to_xml options.reverse_merge(:root => "errors", :skip_types => true)
end
- # Returns an ActiveSupport::OrderedHash that can be used as the JSON representation for this object.
+ # Returns an Hash that can be used as the JSON representation for this object.
def as_json(options=nil)
to_hash
end
2  activemodel/lib/active_model/validations.rb
View
@@ -33,7 +33,7 @@ module ActiveModel
# person.first_name = 'zoolander'
# person.valid? # => false
# person.invalid? # => true
- # person.errors # => #<OrderedHash {:first_name=>["starts with z."]}>
+ # person.errors # => #<Hash {:first_name=>["starts with z."]}>
#
# Note that <tt>ActiveModel::Validations</tt> automatically adds an +errors+ method
# to your instances initialized with a new <tt>ActiveModel::Errors</tt> object, so
2  activemodel/test/cases/errors_test.rb
View
@@ -154,7 +154,7 @@ def test_has_key?
test 'to_hash should return an ordered hash' do
person = Person.new
person.errors.add(:name, "can not be blank")
- assert_instance_of ActiveSupport::OrderedHash, person.errors.to_hash
+ assert_instance_of ::Hash, person.errors.to_hash
end
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
View
@@ -130,13 +130,13 @@ def @contact.favorite_quote; "Constraints are liberating"; end
assert_match %r{"favorite_quote":"Constraints are liberating"}, methods_json
end
- test "should return OrderedHash for errors" do
+ test "should return Hash for errors" do
contact = Contact.new
contact.errors.add :name, "can't be blank"
contact.errors.add :name, "is too short (minimum is 2 characters)"
contact.errors.add :age, "must be 16 or over"
- hash = ActiveSupport::OrderedHash.new
+ hash = {}
hash[:name] = ["can't be blank", "is too short (minimum is 2 characters)"]
hash[:age] = ["must be 16 or over"]
assert_equal hash.to_json, contact.errors.to_json
2  activemodel/test/cases/validations_test.rb
View
@@ -181,7 +181,7 @@ def test_errors_conversions
assert_match %r{<error>Title can't be blank</error>}, xml
assert_match %r{<error>Content can't be blank</error>}, xml
- hash = ActiveSupport::OrderedHash.new
+ hash = {}
hash[:title] = ["can't be blank"]
hash[:content] = ["can't be blank"]
assert_equal t.errors.to_json, hash.to_json
29 activerecord/CHANGELOG.md
View
@@ -72,6 +72,33 @@
## Rails 3.2.0 (unreleased) ##
+* Added 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
+
+ *Olek Janiszewski*
+
* 'on' and 'ON' boolean columns values are type casted to true
*Santiago Pastorino*
@@ -82,7 +109,7 @@
Example:
rake db:migrate SCOPE=blog
- *Piotr Sarnacki*
+ *Piotr Sarnacki*
* Migrations copied from engines are now scoped with engine's name,
for example 01_create_posts.blog.rb. *Piotr Sarnacki*
3  activerecord/lib/active_record/attribute_methods.rb
View
@@ -1,6 +1,5 @@
require 'active_support/core_ext/enumerable'
require 'active_support/deprecation'
-require 'thread'
module ActiveRecord
# = Active Record Attribute Methods
@@ -38,8 +37,6 @@ module ClassMethods
def define_attribute_methods
# Use a mutex; we don't want two thread simaltaneously trying to define
# attribute methods.
- @attribute_methods_mutex ||= Mutex.new
-
@attribute_methods_mutex.synchronize do
return if attribute_methods_generated?
superclass.define_attribute_methods unless self == base_class
2  activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
View
@@ -71,7 +71,7 @@ def type_cast(value, column)
when Date, Time then quoted_date(value)
when Symbol then value.to_s
else
- YAML.dump(value)
+ raise TypeError, "can't cast #{value.class} to #{column.type}"
end
end
16 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
View
@@ -171,15 +171,15 @@ def simplified_type(field_type)
# Extracts the value from a PostgreSQL column default definition.
def self.extract_value_from_default(default)
+ # This is a performance optimization for Ruby 1.9.2 in development.
+ # If the value is nil, we return nil straight away without checking
+ # the regular expressions. If we check each regular expression,
+ # Regexp#=== will call NilClass#to_str, which will trigger
+ # method_missing (defined by whiny nil in ActiveSupport) which
+ # makes this method very very slow.
+ return default unless default
+
case default
- # This is a performance optimization for Ruby 1.9.2 in development.
- # If the value is nil, we return nil straight away without checking
- # the regular expressions. If we check each regular expression,
- # Regexp#=== will call NilClass#to_str, which will trigger
- # method_missing (defined by whiny nil in ActiveSupport) which
- # makes this method very very slow.
- when NilClass
- nil
# Numeric types
when /\A\(?(-?\d+(\.\d*)?\)?)\z/
$1
39 activerecord/lib/active_record/core.rb
View
@@ -1,4 +1,5 @@
require 'active_support/concern'
+require 'thread'
module ActiveRecord
module Core
@@ -80,6 +81,8 @@ def inherited(child_class) #:nodoc:
end
def initialize_generated_modules
+ @attribute_methods_mutex = Mutex.new
+
# force attribute methods to be higher in inheritance hierarchy than other generated methods
generated_attribute_methods
generated_feature_methods
@@ -152,16 +155,8 @@ def relation #:nodoc:
# User.new({ :first_name => 'Jamie', :is_admin => true }, :without_protection => true)
def initialize(attributes = nil, options = {})
@attributes = self.class.initialize_attributes(self.class.column_defaults.dup)
- @association_cache = {}
- @aggregation_cache = {}
- @attributes_cache = {}
- @new_record = true
- @readonly = false
- @destroyed = false
- @marked_for_destruction = false
- @previously_changed = {}
- @changed_attributes = {}
- @relation = nil
+
+ init_internals
ensure_proper_type
@@ -185,13 +180,11 @@ def initialize(attributes = nil, options = {})
# post.title # => 'hello world'
def init_with(coder)
@attributes = self.class.initialize_attributes(coder['attributes'])
- @relation = nil
- @attributes_cache, @previously_changed, @changed_attributes = {}, {}, {}
- @association_cache = {}
- @aggregation_cache = {}
- @readonly = @destroyed = @marked_for_destruction = false
+ init_internals
+
@new_record = false
+
run_callbacks :find
run_callbacks :initialize
@@ -219,7 +212,8 @@ def initialize_dup(other)
@aggregation_cache = {}
@association_cache = {}
- @attributes_cache = {}
+ @attributes_cache = {}
+
@new_record = true
ensure_proper_type
@@ -330,5 +324,18 @@ def inspect
def to_ary # :nodoc:
nil
end
+
+ def init_internals
+ @relation = nil
+ @aggregation_cache = {}
+ @association_cache = {}
+ @attributes_cache = {}
+ @previously_changed = {}
+ @changed_attributes = {}
+ @readonly = false
+ @destroyed = false
+ @marked_for_destruction = false
+ @new_record = true
+ end
end
end
22 activerecord/lib/active_record/locking/pessimistic.rb
View
@@ -38,6 +38,18 @@ module Locking
# account2.save!
# end
#
+ # You can start a transaction and acquire the lock in one go by calling
+ # <tt>with_lock</tt> with a block. The block is called from within
+ # a transaction, the object is already locked. Example:
+ #
+ # account = Account.first
+ # account.with_lock do
+ # # This block is called within a transaction,
+ # # account is already locked.
+ # account.balance -= 100
+ # account.save!
+ # end
+ #
# Database-specific information on row locking:
# MySQL: http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html
# PostgreSQL: http://www.postgresql.org/docs/current/interactive/sql-select.html#SQL-FOR-UPDATE-SHARE
@@ -50,6 +62,16 @@ def lock!(lock = true)
reload(:lock => lock) if persisted?
self
end
+
+ # Wraps the passed block in a transaction, locking the object
+ # before yielding. You pass can the SQL locking clause
+ # as argument (see <tt>lock!</tt>).
+ def with_lock(lock = true)
+ transaction do
+ lock!(lock)
+ yield
+ end
+ end
end
end
end
10 activerecord/lib/active_record/relation/query_methods.rb
View
@@ -75,16 +75,16 @@ def references(*args)
# array, it actually returns a relation object and can have other query
# methods appended to it, such as the other methods in ActiveRecord::QueryMethods.
#
- # This method will also take multiple parameters:
+ # The argument to the method can also be an array of fields.
#
- # >> Model.select(:field, :other_field, :and_one_more)
+ # >> Model.select([:field, :other_field, :and_one_more])
# => [#<Model field: "value", other_field: "value", and_one_more: "value">]
#
- # Any attributes that do not have fields retrieved by a select
- # will return `nil` when the getter method for that attribute is used:
+ # Accessing attributes of an object that do not have fields retrieved by a select
+ # will throw <tt>ActiveModel::MissingAttributeError</tt>:
#
# >> Model.select(:field).first.other_field
- # => nil
+ # => ActiveModel::MissingAttributeError: missing attribute: other_field
def select(value = Proc.new)
if block_given?
to_a.select {|*block_args| value.call(*block_args) }
4 activerecord/test/cases/adapters/sqlite3/quoting_test.rb
View
@@ -70,9 +70,9 @@ def test_type_cast_bigdecimal
assert_equal bd.to_f, @conn.type_cast(bd, nil)
end
- def test_type_cast_unknown
+ def test_type_cast_unknown_should_raise_error
obj = Class.new.new
- assert_equal YAML.dump(obj), @conn.type_cast(obj, nil)
+ assert_raise(TypeError) { @conn.type_cast(obj, nil) }
end
def test_quoted_id
8 activerecord/test/cases/attribute_methods/read_test.rb
View
@@ -1,5 +1,6 @@
require "cases/helper"
require 'active_support/core_ext/object/inclusion'
+require 'thread'
module ActiveRecord
module AttributeMethods
@@ -20,6 +21,13 @@ def self.base_class; self; end
include ActiveRecord::AttributeMethods
+ def self.define_attribute_methods
+ # Created in the inherited/included hook for "proper" ARs
+ @attribute_methods_mutex ||= Mutex.new
+
+ super
+ end
+
def self.column_names
%w{ one two three }
end
33 activerecord/test/cases/base_test.rb
View
@@ -187,6 +187,31 @@ def test_preserving_date_objects
end
end
+ def test_previously_changed
+ topic = Topic.find :first
+ topic.title = '<3<3<3'
+ assert_equal({}, topic.previous_changes)
+
+ topic.save!
+ expected = ["The First Topic", "<3<3<3"]
+ assert_equal(expected, topic.previous_changes['title'])
+ end
+
+ def test_previously_changed_dup
+ topic = Topic.find :first
+ topic.title = '<3<3<3'
+ topic.save!
+
+ t2 = topic.dup
+
+ assert_equal(topic.previous_changes, t2.previous_changes)
+
+ topic.title = "lolwut"
+ topic.save!
+
+ assert_not_equal(topic.previous_changes, t2.previous_changes)
+ end
+
def test_preserving_time_objects
assert_kind_of(
Time, Topic.find(1).bonus_time,
@@ -967,10 +992,9 @@ def test_dup
assert_equal "b", duped_topic.title
# test if the attribute values have been duped
- topic.title = {"a" => "b"}
duped_topic = topic.dup
- duped_topic.title["a"] = "c"
- assert_equal "b", topic.title["a"]
+ duped_topic.title.replace "c"
+ assert_equal "a", topic.title
# test if attributes set as part of after_initialize are duped correctly
assert_equal topic.author_email_address, duped_topic.author_email_address
@@ -981,8 +1005,7 @@ def test_dup
assert_not_equal duped_topic.id, topic.id
duped_topic.reload
- # FIXME: I think this is poor behavior, and will fix it with #5686
- assert_equal({'a' => 'c'}.to_yaml, duped_topic.title)
+ assert_equal("c", duped_topic.title)
end
def test_dup_with_aggregate_of_same_name_as_attribute
20 activerecord/test/cases/locking_test.rb
View
@@ -388,6 +388,26 @@ def test_sane_lock_method
end
end
+ def test_with_lock_commits_transaction
+ person = Person.find 1
+ person.with_lock do
+ person.first_name = 'fooman'
+ person.save!
+ end
+ assert_equal 'fooman', person.reload.first_name
+ end
+
+ def test_with_lock_rolls_back_transaction
+ person = Person.find 1
+ old = person.first_name
+ person.with_lock do
+ person.first_name = 'fooman'
+ person.save!
+ raise 'oops'
+ end rescue nil
+ assert_equal old, person.reload.first_name
+ end
+
if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
def test_no_locks_no_wait
first, second = duel { Person.find 1 }
4 activeresource/lib/active_resource/base.rb
View
@@ -939,12 +939,12 @@ def instantiate_record(record, prefix_options = {})
# Accepts a URI and creates the site URI from that.
def create_site_uri_from(site)
- site.is_a?(URI) ? site.dup : URI.parser.parse(site)
+ site.is_a?(URI) ? site.dup : URI.parse(site)
end
# Accepts a URI and creates the proxy URI from that.
def create_proxy_uri_from(proxy)
- proxy.is_a?(URI) ? proxy.dup : URI.parser.parse(proxy)
+ proxy.is_a?(URI) ? proxy.dup : URI.parse(proxy)
end
# contains a set of the current prefix parameters.
4 activeresource/lib/active_resource/connection.rb
View
@@ -39,14 +39,14 @@ def initialize(site, format = ActiveResource::Formats::JsonFormat)
# Set URI for remote service.
def site=(site)
- @site = site.is_a?(URI) ? site : URI.parser.parse(site)
+ @site = site.is_a?(URI) ? site : URI.parse(site)
@user = URI.parser.unescape(@site.user) if @site.user
@password = URI.parser.unescape(@site.password) if @site.password
end
# Set the proxy for remote service.
def proxy=(proxy)
- @proxy = proxy.is_a?(URI) ? proxy : URI.parser.parse(proxy)
+ @proxy = proxy.is_a?(URI) ? proxy : URI.parse(proxy)
end
# Sets the user for remote service.
2  activesupport/lib/active_support/core_ext/date_time/calculations.rb
View
@@ -2,7 +2,7 @@ class DateTime
class << self
# DateTimes aren't aware of DST rules, so use a consistent non-DST offset when creating a DateTime with an offset in the local zone
def local_offset
- ::Time.local(2007).utc_offset.to_r / 86400
+ ::Time.local(2012).utc_offset.to_r / 86400
end
# Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise returns <tt>Time.now.to_datetime</tt>.
15 activesupport/lib/active_support/core_ext/date_time/conversions.rb
View
@@ -58,32 +58,17 @@ def readable_inspect
alias_method :default_inspect, :inspect
alias_method :inspect, :readable_inspect
- # Converts self to a Ruby Date object; time portion is discarded.
- def to_date
- ::Date.new(year, month, day)
- end unless instance_methods(false).include?(:to_date)
-
# Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class.
# If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time.
def to_time
self.offset == 0 ? ::Time.utc_time(year, month, day, hour, min, sec, sec_fraction * 1000000) : self
end
- # To be able to keep Times, Dates and DateTimes interchangeable on conversions.
- def to_datetime
- self
- end unless instance_methods(false).include?(:to_datetime)
-
def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0)
offset = utc_or_local.to_sym == :local ? local_offset : 0
civil(year, month, day, hour, min, sec, offset)
end
- # Converts datetime to an appropriate format for use in XML.
- def xmlschema
- strftime("%Y-%m-%dT%H:%M:%S%Z")
- end unless instance_methods(false).include?(:xmlschema)
-
# Converts self to a floating-point number of seconds since the Unix epoch.
def to_f
seconds_since_unix_epoch.to_f
38 activesupport/lib/active_support/core_ext/module/delegation.rb
View
@@ -81,25 +81,25 @@ class Module
# no matter whether +nil+ responds to the delegated method. You can get a
# +nil+ instead with the +:allow_nil+ option.
#
- # class Foo
- # attr_accessor :bar
- # def initialize(bar = nil)
- # @bar = bar
- # end
- # delegate :zoo, :to => :bar
- # end
- #
- # Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
- #
- # class Foo
- # attr_accessor :bar
- # def initialize(bar = nil)
- # @bar = bar
- # end
- # delegate :zoo, :to => :bar, :allow_nil => true
- # end
- #
- # Foo.new.zoo # returns nil
+ # class Foo
+ # attr_accessor :bar
+ # def initialize(bar = nil)
+ # @bar = bar
+ # end
+ # delegate :zoo, :to => :bar
+ # end
+ #
+ # Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
+ #
+ # class Foo
+ # attr_accessor :bar
+ # def initialize(bar = nil)
+ # @bar = bar
+ # end
+ # delegate :zoo, :to => :bar, :allow_nil => true
+ # end
+ #
+ # Foo.new.zoo # returns nil
#
def delegate(*methods)
options = methods.pop
2  activesupport/lib/active_support/core_ext/uri.rb
View
@@ -20,7 +20,7 @@ def unescape(str, escaped = /%[a-fA-F\d]{2}/)
module URI
class << self
def parser
- @parser ||= URI.const_defined?(:Parser) ? URI::Parser.new : URI
+ @parser ||= URI::Parser.new
end
end
end
68 activesupport/lib/active_support/tagged_logging.rb
View
@@ -1,5 +1,6 @@
require 'active_support/core_ext/object/blank'
require 'logger'
+require 'active_support/logger'
module ActiveSupport
# Wraps any standard Logger class to provide tagging capabilities. Examples:
@@ -11,52 +12,47 @@ module ActiveSupport
#
# This is used by the default Rails.logger as configured by Railties to make it easy to stamp log lines
# with subdomains, request ids, and anything else to aid debugging of multi-user production applications.
- class TaggedLogging
- def initialize(logger)
- @logger = logger
+ module TaggedLogging
+ class Formatter < ActiveSupport::Logger::SimpleFormatter # :nodoc:
+ # This method is invoked when a log event occurs
+ def call(severity, timestamp, progname, msg)
+ super(severity, timestamp, progname, "#{tags_text}#{msg}")
+ end
+
+ def clear!
+ current_tags.clear
+ end
+
+ def current_tags
+ Thread.current[:activesupport_tagged_logging_tags] ||= []
+ end
+
+ private
+ def tags_text
+ tags = current_tags
+ if tags.any?
+ tags.collect { |tag| "[#{tag}] " }.join
+ end
+ end
+ end
+
+ def self.new(logger)
+ logger.formatter = Formatter.new
+ logger.extend(self)
end
def tagged(*new_tags)
- tags = current_tags
- new_tags = Array(new_tags).flatten.reject(&:blank?)
+ tags = formatter.current_tags
+ new_tags = new_tags.flatten.reject(&:blank?)
tags.concat new_tags
yield
ensure
tags.pop(new_tags.size)
end
- def add(severity, message = nil, progname = nil, &block)
- @logger.add(severity, "#{tags_text}#{message}", progname, &block)
- end
-
- %w( fatal error warn info debug unknown ).each do |severity|
- eval <<-EOM, nil, __FILE__, __LINE__ + 1
- def #{severity}(progname = nil, &block) # def warn(progname = nil, &block)
- add(Logger::#{severity.upcase}, progname, &block) # add(Logger::WARN, progname, &block)
- end # end
- EOM
- end
-
def flush
- current_tags.clear
- @logger.flush if @logger.respond_to?(:flush)
- end
-
- def method_missing(method, *args)
- @logger.send(method, *args)
- end
-
- protected
-
- def tags_text
- tags = current_tags
- if tags.any?
- tags.collect { |tag| "[#{tag}] " }.join
- end
- end
-
- def current_tags
- Thread.current[:activesupport_tagged_logging_tags] ||= []
+ formatter.clear!
+ super if defined?(super)
end
end
end
8 activesupport/test/core_ext/uri_ext_test.rb
View
@@ -7,11 +7,7 @@ class URIExtTest < ActiveSupport::TestCase
def test_uri_decode_handle_multibyte
str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
- if URI.const_defined?(:Parser)
- parser = URI::Parser.new
- assert_equal str, parser.unescape(parser.escape(str))
- else
- assert_equal str, URI.unescape(URI.escape(str))
- end
+ parser = URI::Parser.new
+ assert_equal str, parser.unescape(parser.escape(str))
end
end
23 railties/guides/code/getting_started/Gemfile
View
@@ -1,8 +1,9 @@
-source 'http://rubygems.org'
+source 'https://rubygems.org'
+
+gem 'rails', '3.2.0'
-gem 'rails', '3.1.0'
# Bundle edge Rails instead:
-# gem 'rails', :git => 'git://github.com/rails/rails.git'
+# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'sqlite3'
@@ -10,13 +11,23 @@ gem 'sqlite3'
# Gems used only for assets and not required
# in production environments by default.
group :assets do
- gem 'sass-rails', " ~> 3.1.0"
- gem 'coffee-rails', "~> 3.1.0"
- gem 'uglifier'
+ gem 'sass-rails', '~> 3.2.3'
+ gem 'coffee-rails', '~> 3.2.1'
+
+ # See https://github.com/sstephenson/execjs#readme for more supported runtimes
+ # gem 'therubyracer'
+
+ gem 'uglifier', '>= 1.0.3'
end
gem 'jquery-rails'
+# To use ActiveModel has_secure_password
+# gem 'bcrypt-ruby', '~> 3.0.0'
+
+# To use Jbuilder templates for JSON
+# gem 'jbuilder'
+
# Use unicorn as the web server
# gem 'unicorn'
12 railties/guides/code/getting_started/app/assets/javascripts/application.js
View
@@ -1,9 +1,15 @@
-// This is a manifest file that'll be compiled into including all the files listed below.
-// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
-// be included in the compiled file accessible from http://example.com/assets/application.js
+// This is a manifest file that'll be compiled into application.js, which will include all the files
+// listed below.
+//
+// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
+//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
+// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
+// GO AFTER THE REQUIRES BELOW.
+//
//= require jquery
//= require jquery_ujs
//= require_tree .
16 railties/guides/code/getting_started/app/assets/stylesheets/application.css
View
@@ -1,7 +1,13 @@
/*
- * This is a manifest file that'll automatically include all the stylesheets available in this directory
- * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
- * the top of the compiled file, but it's generally better to create a new file per style scope.
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
+ * listed below.
+ *
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
+ *
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
+ * compiled file, but it's generally better to create a new file per style scope.
+ *
*= require_self
- *= require_tree .
-*/
+ *= require_tree .
+*/
2  railties/guides/code/getting_started/app/views/layouts/application.html.erb
View
@@ -6,7 +6,7 @@
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
-<body style="background: #EEEEEE;">
+<body>
<%= yield %>
8 railties/guides/code/getting_started/config/application.rb
View
@@ -4,7 +4,7 @@
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
- Bundler.require *Rails.groups(:assets => %w(development test))
+ Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
@@ -40,6 +40,12 @@ class Application < Rails::Application
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
+ # Enforce whitelist mode for mass assignment.
+ # This will create an empty whitelist of attributes available for mass-assignment for all models
+ # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
+ # parameters by using an attr_accessible or attr_protected declaration.
+ # config.active_record.whitelist_attributes = true
+
# Enable the asset pipeline
config.assets.enabled = true
6 railties/guides/code/getting_started/config/environments/test.rb
View
@@ -26,9 +26,9 @@
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
+ # Raise exception on mass assignment protection for Active Record models
+ config.active_record.mass_assignment_sanitizer = :strict
+
# Print deprecation notices to the stderr
config.active_support.deprecation = :stderr
-
- # Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets
- config.assets.allow_debugging = true
end
5 railties/guides/code/getting_started/config/initializers/inflections.rb
View
@@ -8,3 +8,8 @@
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end
+#
+# These inflection rules are supported but not enabled by default:
+# ActiveSupport::Inflector.inflections do |inflect|
+# inflect.acronym 'RESTful'
+# end
8 railties/guides/code/getting_started/config/routes.rb
View
@@ -1,7 +1,7 @@
Blog::Application.routes.draw do
- resources :posts do
- resources :comments
- end
+ resources :posts do
+ resources :comments
+ end
get "home/index"
@@ -60,5 +60,5 @@
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
- # match ':controller(/:action(/:id(.:format)))'
+ # match ':controller(/:action(/:id))(.:format)'
end
1  railties/guides/code/getting_started/public/500.html
View
@@ -20,7 +20,6 @@
<!-- This file lives in public/500.html -->
<div class="dialog">
<h1>We're sorry, but something went wrong.</h1>
- <p>We've been notified about this issue and we'll take a look at it shortly.</p>
</div>
</body>
</html>
54 railties/guides/source/3_2_release_notes.textile
View
@@ -27,6 +27,7 @@ h4. What to update in your apps
** <tt>rails = 3.2.0</tt>
** <tt>sass-rails ~> 3.2.3</tt>
** <tt>coffee-rails ~> 3.2.1</tt>
+** <tt>uglifier >= 1.0.3</tt>
* Rails 3.2 deprecates <tt>vendor/plugins</tt> and Rails 4.0 will remove them completely. You can start replacing 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>.
@@ -138,10 +139,16 @@ will create indexes for +title+ and +author+ with the latter being an unique ind
* Remove old <tt>config.paths.app.controller</tt> API in favor of <tt>config.paths["app/controller"]</tt>.
-h4. Deprecations
+h4(#railties_deprec