diff options
-rw-r--r-- | actionview/CHANGELOG.md | 10 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/form_options_helper.rb | 6 | ||||
-rw-r--r-- | actionview/test/template/form_options_helper_test.rb | 10 | ||||
-rw-r--r-- | activerecord/lib/active_record/associations/has_many_association.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/associations/has_one_association.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/locale/en.yml | 4 | ||||
-rw-r--r-- | guides/source/4_0_release_notes.md | 8 | ||||
-rw-r--r-- | guides/source/debugging_rails_applications.md | 31 | ||||
-rw-r--r-- | railties/lib/rails/application/finisher.rb | 4 | ||||
-rw-r--r-- | railties/lib/rails/templates/rails/welcome/index.html.erb | 2 | ||||
-rw-r--r-- | railties/test/application/routing_test.rb | 2 |
11 files changed, 69 insertions, 12 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 60ddace7e4..fe8bbde445 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,13 @@ +* Element of the `grouped_options_for_select` can + optionally contain html attributes as the last element of the array. + + Example: + grouped_options_for_select( + [["North America", [['United States','US'],"Canada"], :data => { :foo => 'bar' }]] + ) + + *Vasiliy Ermolovich* + * Fix default rendered format problem when calling `render` without :content_type option. It should return :html. Fix #11393. diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb index 4e9ef94ff3..8351548f06 100644 --- a/actionview/lib/action_view/helpers/form_options_helper.rb +++ b/actionview/lib/action_view/helpers/form_options_helper.rb @@ -520,12 +520,16 @@ module ActionView end grouped_options.each do |container| + html_attributes = option_html_attributes(container) + if divider label = divider else label, container = container end - body.safe_concat content_tag(:optgroup, options_for_select(container, selected_key), :label => label) + + html_attributes = { :label => label }.merge(html_attributes) + body.safe_concat content_tag(:optgroup, options_for_select(container, selected_key), html_attributes) end body diff --git a/actionview/test/template/form_options_helper_test.rb b/actionview/test/template/form_options_helper_test.rb index 8c90a58a84..3ec138b639 100644 --- a/actionview/test/template/form_options_helper_test.rb +++ b/actionview/test/template/form_options_helper_test.rb @@ -302,6 +302,16 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_grouped_options_for_select_with_array_and_html_attributes + assert_dom_equal( + "<optgroup label=\"North America\" data-foo=\"bar\"><option value=\"US\">United States</option>\n<option value=\"Canada\">Canada</option></optgroup><optgroup label=\"Europe\" disabled=\"disabled\"><option value=\"GB\">Great Britain</option>\n<option value=\"Germany\">Germany</option></optgroup>", + grouped_options_for_select([ + ["North America", [['United States','US'],"Canada"], :data => { :foo => 'bar' }], + ["Europe", [["Great Britain","GB"], "Germany"], :disabled => 'disabled'] + ]) + ) + end + def test_grouped_options_for_select_with_optional_divider assert_dom_equal( "<optgroup label=\"----------\"><option value=\"US\">US</option>\n<option value=\"Canada\">Canada</option></optgroup><optgroup label=\"----------\"><option value=\"GB\">GB</option>\n<option value=\"Germany\">Germany</option></optgroup>", diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 6e722616bf..607ed0da46 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -15,7 +15,7 @@ module ActiveRecord when :restrict_with_error unless empty? record = klass.human_attribute_name(reflection.name).downcase - owner.errors.add(:base, :"restrict_dependent_destroy.has_many", record: record) + owner.errors.add(:base, :"restrict_dependent_destroy.many", record: record) false end diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index 5791602846..3ab1ea1ff4 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -12,7 +12,7 @@ module ActiveRecord when :restrict_with_error if load_target record = klass.human_attribute_name(reflection.name).downcase - owner.errors.add(:base, :"restrict_dependent_destroy.has_one", record: record) + owner.errors.add(:base, :"restrict_dependent_destroy.one", record: record) false end diff --git a/activerecord/lib/active_record/locale/en.yml b/activerecord/lib/active_record/locale/en.yml index 3a81e15532..b1fbd38622 100644 --- a/activerecord/lib/active_record/locale/en.yml +++ b/activerecord/lib/active_record/locale/en.yml @@ -15,8 +15,8 @@ en: messages: record_invalid: "Validation failed: %{errors}" restrict_dependent_destroy: - has_one: "Cannot delete record because a dependent %{record} exists" - has_many: "Cannot delete record because dependent %{record} exist" + one: "Cannot delete record because a dependent %{record} exists" + many: "Cannot delete record because dependent %{record} exist" # Append your own errors here or at the model/attributes scope. # You can define own errors for models or model attributes. diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md index 006d0cda92..8be7a86d20 100644 --- a/guides/source/4_0_release_notes.md +++ b/guides/source/4_0_release_notes.md @@ -68,19 +68,19 @@ Major Features * **Strong parameters** ([commit](https://github.com/rails/rails/commit/a8f6d5c6450a7fe058348a7f10a908352bb6c7fc)) - Only allow whitelisted parameters to update model objects (`params.permit(:title, :text)`). * **Routing concerns** ([commit](https://github.com/rails/rails/commit/0dd24728a088fcb4ae616bb5d62734aca5276b1b)) - In the routing DSL, factor out common subroutes (`comments` from `/posts/1/comments` and `/videos/1/comments`). * **ActionController::Live** ([commit](https://github.com/rails/rails/commit/af0a9f9eefaee3a8120cfd8d05cbc431af376da3)) - Stream JSON with `response.stream`. - * **Declarative ETags** ([commit](https://github.com/rails/rails/commit/ed5c938fa36995f06d4917d9543ba78ed506bb8d)) - Set ETag and Last-Modified headers using `etag` and `fresh_when`. + * **Declarative ETags** ([commit](https://github.com/rails/rails/commit/ed5c938fa36995f06d4917d9543ba78ed506bb8d)) - Add controller-level etag additions that will be part of the action etag computation * **[Russian doll caching](http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works)** ([commit](https://github.com/rails/rails/commit/4154bf012d2bec2aae79e4a49aa94a70d3e91d49)) - Cache nested fragments of views. Each fragment expires based on a set of dependencies (a cache key). The cache key is usually a template version number and a model object. * **Turbolinks** ([commit](https://github.com/rails/rails/commit/e35d8b18d0649c0ecc58f6b73df6b3c8d0c6bb74)) - Serve only one initial HTML page. When the user navigates to another page, use pushState to update the URL and use AJAX to update the title and body. - * **Decouple ActionView from ActionController** ([commit](https://github.com/rails/rails/commit/78b0934dd1bb84e8f093fb8ef95ca99b297b51cd)) - ActionView is moved outside of ActionPack. + * **Decouple ActionView from ActionController** ([commit](https://github.com/rails/rails/commit/78b0934dd1bb84e8f093fb8ef95ca99b297b51cd)) - ActionView was decoupled from ActionPack and will be moved to a separated gem in Rails 4.1. * **Do not depend on ActiveModel** ([commit](https://github.com/rails/rails/commit/166dbaa7526a96fdf046f093f25b0a134b277a68)) - ActionPack no longer depends on ActiveModel. ### General - * **ActiveModel::Model** ([commit](https://github.com/rails/rails/commit/3b822e91d1a6c4eab0064989bbd07aae3a6d0d08)) - `ActiveModel::Model` is extracted from ActiveRecord. `ActiveModel::Model` provides validations and `form_for` for normal Ruby objects. + * **ActiveModel::Model** ([commit](https://github.com/rails/rails/commit/3b822e91d1a6c4eab0064989bbd07aae3a6d0d08)) - `ActiveModel::Model`, a mixin to make normal Ruby objects to work with ActionPack out of box (ex. for `form_for`) * **New scope API** ([commit](https://github.com/rails/rails/commit/50cbc03d18c5984347965a94027879623fc44cce)) - Scopes must always use callables. * **Schema cache dump** ([commit](https://github.com/rails/rails/commit/5ca4fc95818047108e69e22d200e7a4a22969477)) - To improve Rails boot time, instead of loading the schema directly from the database, load the schema from a dump file. * **Support for specifying transaction isolation level** ([commit](https://github.com/rails/rails/commit/392eeecc11a291e406db927a18b75f41b2658253)) - Choose whether repeatable reads or improved performance (less locking) is more important. - * **Dalli** ([commit](https://github.com/rails/rails/commit/82663306f428a5bbc90c511458432afb26d2f238)) - For the memcache session store, use the Dalli memcache client. + * **Dalli** ([commit](https://github.com/rails/rails/commit/82663306f428a5bbc90c511458432afb26d2f238)) - Use Dalli memcache client for the memcache store. * **Notifications start & finish** ([commit](https://github.com/rails/rails/commit/f08f8750a512f741acb004d0cebe210c5f949f28)) - Active Support instrumentation reports start and finish notifications to subscribers. * **Thread safe by default** ([commit](https://github.com/rails/rails/commit/5d416b907864d99af55ebaa400fff217e17570cd)) - Rails can run in threaded app servers without additional configuration. Note: Check that the gems you are using are threadsafe. * **PATCH verb** ([commit](https://github.com/rails/rails/commit/eed9f2539e3ab5a68e798802f464b8e4e95e619e)) - In Rails, PATCH replaces PUT. PATCH is used for partial updates of resources. diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md index 77a2dd4b18..50ee934b87 100644 --- a/guides/source/debugging_rails_applications.md +++ b/guides/source/debugging_rails_applications.md @@ -209,6 +209,37 @@ logger.tagged("BCX", "Jason") { logger.info "Stuff" } # Logs " logger.tagged("BCX") { logger.tagged("Jason") { logger.info "Stuff" } } # Logs "[BCX] [Jason] Stuff" ``` +### Impact of Logs on Performance +Logging will always have a small impact on performance of your rails app, + particularly when logging to disk.However, there are a few subtleties: + +Using the `:debug` level will have a greater performance penalty than `:fatal`, + as a far greater number of strings are being evaluated and written to the + log output (e.g. disk). + +Another potential pitfall is that if you have many calls to `Logger` like this + in your code: + +```ruby +logger.debug "Person attributes hash: #{@person.attributes.inspect}" +``` + +In the above example, There will be a performance impact even if the allowed +output level doesn't include debug. The reason is that Ruby has to evaluate +these strings, which includes instantiating the somewhat heavy `String` object +and interpolating the variables, and which takes time. +Therefore, it's recommended to pass blocks to the logger methods, as these are +only evaluated if the output level is the same or included in the allowed level +(i.e. lazy loading). The same code rewritten would be: + +```ruby +logger.debug {"Person attibutes hash: #{@person.attributes.inspect}"} +``` + +The contents of the block, and therefore the string interpolation, is only +evaluated if debug is enabled. This performance savings is only really +noticeable with large amounts of logging, but it's a good practice to employ. + Debugging with the `debugger` gem --------------------------------- diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index 7a1bb1e25c..1e4c6ca921 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -25,9 +25,11 @@ module Rails get '/rails/info/properties' => "rails/info#properties" get '/rails/info/routes' => "rails/info#routes" get '/rails/info' => "rails/info#index" - get '/' => "rails/welcome#index" end end + app.routes.append do + get '/' => "rails/welcome#index" + end end initializer :build_middleware_stack do diff --git a/railties/lib/rails/templates/rails/welcome/index.html.erb b/railties/lib/rails/templates/rails/welcome/index.html.erb index eb620caa00..dd35835c6f 100644 --- a/railties/lib/rails/templates/rails/welcome/index.html.erb +++ b/railties/lib/rails/templates/rails/welcome/index.html.erb @@ -227,7 +227,7 @@ <li> <h2>Set up a root route to replace this page</h2> - <p>You're seeing this page because you're running in development mode and you haven't set a root route yet.</p> + <p>You're seeing this page because you haven't set a root route yet.</p> <p>Routes are set up in <span class="filename">config/routes.rb</span>.</p> </li> diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb index 8576a2b738..e1679315f8 100644 --- a/railties/test/application/routing_test.rb +++ b/railties/test/application/routing_test.rb @@ -60,7 +60,7 @@ module ApplicationTests test "rails/welcome in production" do app("production") get "/" - assert_equal 404, last_response.status + assert_equal 200, last_response.status end test "rails/info/routes in production" do |