aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--actionmailer/CHANGELOG.md10
-rw-r--r--actionmailer/lib/action_mailer/base.rb28
-rw-r--r--actionmailer/test/base_test.rb50
-rw-r--r--actionpack/CHANGELOG.md33
-rw-r--r--actionpack/lib/abstract_controller/base.rb5
-rw-r--r--actionpack/lib/action_controller/base.rb4
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb8
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb20
-rw-r--r--actionpack/lib/action_controller/test_case.rb9
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb28
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/base.rb5
-rw-r--r--actionpack/lib/action_view/helpers/tags/text_area.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/text_field.rb3
-rw-r--r--actionpack/test/abstract/abstract_controller_test.rb3
-rw-r--r--actionpack/test/controller/base_test.rb1
-rw-r--r--actionpack/test/controller/request_forgery_protection_test.rb4
-rw-r--r--actionpack/test/controller/send_file_test.rb4
-rw-r--r--actionpack/test/template/active_model_helper_test.rb6
-rw-r--r--actionpack/test/template/form_helper_test.rb324
-rw-r--r--actionpack/test/template/form_options_helper_test.rb8
-rw-r--r--actionpack/test/template/javascript_helper_test.rb2
-rw-r--r--actionpack/test/template/test_case_test.rb6
-rw-r--r--activemodel/CHANGELOG.md13
-rw-r--r--activemodel/lib/active_model/conversion.rb4
-rw-r--r--activemodel/lib/active_model/naming.rb1
-rw-r--r--activemodel/lib/active_model/serialization.rb16
-rw-r--r--activemodel/test/cases/conversion_test.rb2
-rw-r--r--activemodel/test/cases/serialization_test.rb26
-rw-r--r--activerecord/CHANGELOG.md26
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb73
-rw-r--r--activerecord/lib/active_record/base.rb3
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb35
-rw-r--r--activerecord/lib/active_record/core.rb2
-rw-r--r--activerecord/lib/active_record/dynamic_finder_match.rb26
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb2
-rw-r--r--activerecord/lib/active_record/persistence.rb4
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb2
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb2
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb7
-rw-r--r--activerecord/test/cases/connection_pool_test.rb63
-rw-r--r--activerecord/test/cases/dynamic_finder_match_test.rb8
-rw-r--r--activerecord/test/cases/finder_respond_to_test.rb10
-rw-r--r--activerecord/test/cases/finder_test.rb26
-rw-r--r--activerecord/test/cases/multiple_db_test.rb8
-rw-r--r--activerecord/test/cases/relations_test.rb12
-rw-r--r--activeresource/CHANGELOG.md5
-rw-r--r--activesupport/CHANGELOG.md5
-rw-r--r--activesupport/lib/active_support/cache.rb1
-rw-r--r--activesupport/lib/active_support/dependencies/autoload.rb11
-rw-r--r--activesupport/lib/active_support/tagged_logging.rb4
-rw-r--r--activesupport/test/caching_test.rb4
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb2
-rw-r--r--rails.gemspec2
-rw-r--r--railties/CHANGELOG.md5
-rw-r--r--railties/guides/source/action_view_overview.textile10
-rw-r--r--railties/guides/source/active_record_querying.textile2
-rw-r--r--railties/guides/source/api_app.textile21
-rw-r--r--railties/guides/source/configuring.textile8
-rw-r--r--railties/guides/source/contributing_to_ruby_on_rails.textile2
-rw-r--r--railties/guides/source/form_helpers.textile22
-rw-r--r--railties/guides/source/nested_model_forms.textile12
-rw-r--r--railties/lib/rails/application.rb8
-rw-r--r--railties/lib/rails/application/bootstrap.rb6
-rw-r--r--railties/lib/rails/application/configuration.rb3
-rw-r--r--railties/lib/rails/commands/server.rb2
-rw-r--r--railties/lib/rails/configuration.rb51
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb5
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb21
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb4
-rw-r--r--railties/test/application/configuration_test.rb18
-rw-r--r--railties/test/application/initializers/frameworks_test.rb16
-rw-r--r--railties/test/application/middleware_test.rb3
-rw-r--r--railties/test/application/rake/migrations_test.rb163
-rw-r--r--railties/test/application/rake/notes_test.rb3
-rw-r--r--railties/test/application/rake_test.rb25
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb13
-rw-r--r--railties/test/generators/scaffold_generator_test.rb18
83 files changed, 969 insertions, 459 deletions
diff --git a/.travis.yml b/.travis.yml
index 68d5c594ae..674d41c88f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,6 @@
script: 'ci/travis.rb'
+before_install:
+ - gem install bundler
rvm:
- 1.9.3
env:
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md
index da5d5c4086..be7b82eecc 100644
--- a/actionmailer/CHANGELOG.md
+++ b/actionmailer/CHANGELOG.md
@@ -1,6 +1,11 @@
-## Rails 4.0.0 (unreleased) ##
+## Rails 3.2.3 (unreleased) ##
-* No changes
+* Upgrade mail version to 2.4.3 *ML*
+
+
+## Rails 3.2.2 (March 1, 2012) ##
+
+* No changes.
## Rails 3.2.1 (January 26, 2012) ##
@@ -128,6 +133,7 @@
* Mail does not have "quoted_body", "quoted_subject" etc. All of these are accessed via body.encoded, subject.encoded etc
* Every object in a Mail object returns an object, never a string. So Mail.body returns a Mail::Body class object, need to call #encoded or #decoded to get the string you want.
+
* Mail::Message#set_content_type does not exist, it is simply Mail::Message#content_type
* Every mail message gets a unique message_id unless you specify one, had to change all the tests that check for equality with expected.encoded == actual.encoded to first replace their message_ids with control values
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 1800ff5839..64f82f24a2 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -267,6 +267,33 @@ module ActionMailer #:nodoc:
# set something in the defaults using a proc, and then set the same thing inside of your
# mailer method, it will get over written by the mailer method.
#
+ # = Callbacks
+ #
+ # You can specify callbacks using before_filter and after_filter for configuring your messages.
+ # This may be useful, for example, when you want to add default inline attachments for all
+ # messages sent out by a certain mailer class:
+ #
+ # class Notifier < ActionMailer::Base
+ # before_filter :add_inline_attachment!
+ #
+ # def welcome
+ # mail
+ # end
+ #
+ # private
+ #
+ # def add_inline_attachment!
+ # attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
+ # end
+ # end
+ #
+ # Callbacks in ActionMailer are implemented using AbstractController::Callbacks, so you
+ # can define and configure callbacks in the same manner that you would use callbacks in
+ # classes that inherit from ActionController::Base.
+ #
+ # Note that unless you have a specific reason to do so, you should prefer using before_filter
+ # rather than after_filter in your ActionMailer classes so that headers are parsed properly.
+ #
# = Configuration options
#
# These options are specified on the class level, like
@@ -330,6 +357,7 @@ module ActionMailer #:nodoc:
include AbstractController::Helpers
include AbstractController::Translation
include AbstractController::AssetPaths
+ include AbstractController::Callbacks
self.protected_instance_variables = [:@_action_has_layout]
diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb
index 65550ab505..aed3ee1874 100644
--- a/actionmailer/test/base_test.rb
+++ b/actionmailer/test/base_test.rb
@@ -1,5 +1,7 @@
# encoding: utf-8
require 'abstract_unit'
+require 'set'
+
require 'active_support/time'
require 'mailers/base_mailer'
@@ -550,6 +552,52 @@ class BaseTest < ActiveSupport::TestCase
assert_equal("Thanks for signing up this afternoon", mail.subject)
end
+ test "modifying the mail message with a before_filter" do
+ class BeforeFilterMailer < ActionMailer::Base
+ before_filter :add_special_header!
+
+ def welcome ; mail ; end
+
+ private
+ def add_special_header!
+ headers('X-Special-Header' => 'Wow, so special')
+ end
+ end
+
+ assert_equal('Wow, so special', BeforeFilterMailer.welcome['X-Special-Header'].to_s)
+ end
+
+ test "modifying the mail message with an after_filter" do
+ class AfterFilterMailer < ActionMailer::Base
+ after_filter :add_special_header!
+
+ def welcome ; mail ; end
+
+ private
+ def add_special_header!
+ headers('X-Special-Header' => 'Testing')
+ end
+ end
+
+ assert_equal('Testing', AfterFilterMailer.welcome['X-Special-Header'].to_s)
+ end
+
+ test "adding an inline attachment using a before_filter" do
+ class DefaultInlineAttachmentMailer < ActionMailer::Base
+ before_filter :add_inline_attachment!
+
+ def welcome ; mail ; end
+
+ private
+ def add_inline_attachment!
+ attachments.inline["footer.jpg"] = 'hey there'
+ end
+ end
+
+ mail = DefaultInlineAttachmentMailer.welcome
+ assert_equal('image/jpeg; filename=footer.jpg', mail.attachments.inline.first['Content-Type'].to_s)
+ end
+
test "action methods should be refreshed after defining new method" do
class FooMailer < ActionMailer::Base
# this triggers action_methods
@@ -559,7 +607,7 @@ class BaseTest < ActiveSupport::TestCase
end
end
- assert_equal ["notify"], FooMailer.action_methods
+ assert_equal Set.new(["notify"]), FooMailer.action_methods
end
protected
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 78ac05389c..ebaf2d407c 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,12 +1,18 @@
## Rails 4.0.0 (unreleased) ##
-* Adds support for layouts when rendering a partial with a given collection. *serabe*
+* Add `include_hidden` option to select tag. With `:include_hidden => true` select with `multiple` attribute doesn't generate hidden input with blank value. *Vasiliy Ermolovich*
-* Allows the route helper `root` to take a string argument. For example, `root 'pages#main'`. *bcardarella*
+* Removed default `size` option from the `text_field`, `search_field`, `telephone_field`, `url_field`, `email_field` helpers. *Philip Arndt*
-* Forms of persisted records use always PATCH (via the `_method` hack). *fxn*
+* Removed default `cols` and `rows` options from the `text_area` helper. *Philip Arndt*
-* For resources, both PATCH and PUT are routed to the `update` action. *fxn*
+* Adds support for layouts when rendering a partial with a given collection. *serabe*
+
+* Allows the route helper `root` to take a string argument. For example, `root 'pages#main'`. *bcardarella*
+
+* Forms of persisted records use always PATCH (via the `_method` hack). *fxn*
+
+* For resources, both PATCH and PUT are routed to the `update` action. *fxn*
* Don't ignore `force_ssl` in development. This is a change of behavior - use a `:if` condition to recreate the old behavior.
@@ -115,6 +121,21 @@
HTML5 `mark` element. *Brian Cardarella*
+## Rails 3.2.3 (unreleased) ##
+
+* Upgrade rack-cache to 1.2. *José Valim*
+
+* ActionController::SessionManagement is removed. *Santiago Pastorino*
+
+* Since the router holds references to many parts of the system like engines, controllers and the application itself, inspecting the route set can actually be really slow, therefore we default alias inspect to to_s. *José Valim*
+
+* Add a new line after the textarea opening tag. Closes #393 *Rafael Mendonça França*
+
+* Always pass a respond block from to responder. We should let the responder decide what to do with the given overridden response block, and not short circuit it. *Prem Sichanugrist*
+
+* Fixes layout rendering regression from 3.2.2. *José Valim*
+
+
## Rails 3.2.2 (March 1, 2012) ##
* Format lookup for partials is derived from the format in which the template is being rendered. Closes #5025 part 2 *Santiago Pastorino*
@@ -305,6 +326,7 @@
returned by the class method attribute_names will be wrapped. This fixes
the wrapping of nested attributes by adding them to attr_accessible.
+
## Rails 3.1.4 (March 1, 2012) ##
* Skip assets group in Gemfile and all assets configurations options
@@ -321,6 +343,7 @@
* Assets should use the request protocol by default or default to relative if no request is available *Jonathan del Strother*
+
## Rails 3.1.3 (November 20, 2011) ##
* Downgrade sprockets to ~> 2.0.3. Using 2.1.0 caused regressions.
@@ -330,6 +353,7 @@
*Jon Leighton*
+
## Rails 3.1.2 (November 18, 2011) ##
* Fix XSS security vulnerability in the `translate` helper method. When using interpolation
@@ -371,6 +395,7 @@
* Ensure users upgrading from 3.0.x to 3.1.x will properly upgrade their flash object in session (issues #3298 and #2509)
+
## Rails 3.1.1 (October 07, 2011) ##
* javascript_path and stylesheet_path now refer to /assets if asset pipelining
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb
index 43cea3b79e..b068846a13 100644
--- a/actionpack/lib/abstract_controller/base.rb
+++ b/actionpack/lib/abstract_controller/base.rb
@@ -1,4 +1,5 @@
require 'erubis'
+require 'set'
require 'active_support/configurable'
require 'active_support/descendants_tracker'
require 'active_support/core_ext/module/anonymous'
@@ -59,7 +60,7 @@ module AbstractController
# itself. Finally, #hidden_actions are removed.
#
# ==== Returns
- # * <tt>array</tt> - A list of all methods that should be considered actions.
+ # * <tt>set</tt> - A set of all methods that should be considered actions.
def action_methods
@action_methods ||= begin
# All public instance methods of this class, including ancestors
@@ -72,7 +73,7 @@ module AbstractController
hidden_actions.to_a
# Clear out AS callback method pollution
- methods.reject { |method| method =~ /_one_time_conditions/ }
+ Set.new(methods.reject { |method| method =~ /_one_time_conditions/ })
end
end
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 95de595f4f..6ce78f34b5 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -174,8 +174,8 @@ module ActionController
# Shortcut helper that returns all the ActionController modules except the ones passed in the argument:
#
# class MetalController
- # ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |module|
- # include module
+ # ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |left|
+ # include left
# end
# end
#
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index f413a2f318..73e044a092 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -259,8 +259,12 @@ module ActionController #:nodoc:
end
end
- # Collects mimes and return the response for the negotiated format. Returns
- # nil if :not_acceptable was sent to the client.
+ # Returns a Collector object containing the appropriate mime-type response
+ # for the current request, based on the available responses defined by a block.
+ # In typical usage this is the block passed to +respond_with+ or +respond_to+.
+ #
+ # Sends :not_acceptable to the client and returns nil if no suitable format
+ # is available.
#
def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc:
mimes ||= collect_mimes_from_class_level
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index afa9243f02..3081c14c09 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -37,6 +37,10 @@ module ActionController #:nodoc:
config_accessor :request_forgery_protection_token
self.request_forgery_protection_token ||= :authenticity_token
+ # Controls how unverified request will be handled
+ config_accessor :request_forgery_protection_method
+ self.request_forgery_protection_method ||= :reset_session
+
# Controls whether request forgery protection is turned on or not. Turned off by default only in test mode.
config_accessor :allow_forgery_protection
self.allow_forgery_protection = true if allow_forgery_protection.nil?
@@ -64,8 +68,10 @@ module ActionController #:nodoc:
# Valid Options:
#
# * <tt>:only/:except</tt> - Passed to the <tt>before_filter</tt> call. Set which actions are verified.
+ # * <tt>:with</tt> - Set the method to handle unverified request. Valid values: <tt>:exception</tt> and <tt>:reset_session</tt> (default).
def protect_from_forgery(options = {})
self.request_forgery_protection_token ||= :authenticity_token
+ self.request_forgery_protection_method = options.delete(:with) if options.key?(:with)
prepend_before_filter :verify_authenticity_token, options
end
end
@@ -80,9 +86,19 @@ module ActionController #:nodoc:
end
# This is the method that defines the application behavior when a request is found to be unverified.
- # By default, \Rails resets the session when it finds an unverified request.
+ # By default, \Rails uses <tt>request_forgery_protection_method</tt> when it finds an unverified request:
+ #
+ # * <tt>:reset_session</tt> - Resets the session.
+ # * <tt>:exception</tt>: - Raises ActionController::InvalidAuthenticityToken exception.
def handle_unverified_request
- reset_session
+ case request_forgery_protection_method
+ when :exception
+ raise ActionController::InvalidAuthenticityToken
+ when :reset_session
+ reset_session
+ else
+ raise ArgumentError, 'Invalid request forgery protection method, use :exception or :reset_session'
+ end
end
# Returns true or false if a request is verified. Checks:
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index e9a3ec5a22..7af30ed690 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -56,6 +56,9 @@ module ActionController
# # assert that the "new" view template was rendered
# assert_template "new"
#
+ # # assert that the exact template "admin/posts/new" was rendered
+ # assert_template %r{\Aadmin/posts/new\Z}
+ #
# # assert that the "_customer" partial was rendered twice
# assert_template :partial => '_customer', :count => 2
#
@@ -74,11 +77,11 @@ module ActionController
response.body
case options
- when NilClass, String, Symbol
+ when NilClass, String, Symbol, Regexp
options = options.to_s if Symbol === options
rendered = @templates
msg = message || sprintf("expecting <%s> but rendering with <%s>",
- options, rendered.keys)
+ options.inspect, rendered.keys)
assert_block(msg) do
if options
rendered.any? { |t,num| t.match(options) }
@@ -121,6 +124,8 @@ module ActionController
assert @partials.empty?,
"Expected no partials to be rendered"
end
+ else
+ raise ArgumentError, "assert_template only accepts a String, Symbol, Hash, Regexp, or nil"
end
end
end
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 54e3032298..43d5cf1471 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -56,10 +56,10 @@ module ActionView
# <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
# </div>
# <label for="person_first_name">First name</label>:
- # <input id="person_first_name" name="person[first_name]" size="30" type="text" /><br />
+ # <input id="person_first_name" name="person[first_name]" type="text" /><br />
#
# <label for="person_last_name">Last name</label>:
- # <input id="person_last_name" name="person[last_name]" size="30" type="text" /><br />
+ # <input id="person_last_name" name="person[last_name]" type="text" /><br />
#
# <input name="commit" type="submit" value="Create Person" />
# </form>
@@ -87,10 +87,10 @@ module ActionView
# <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
# </div>
# <label for="person_first_name">First name</label>:
- # <input id="person_first_name" name="person[first_name]" size="30" type="text" value="John" /><br />
+ # <input id="person_first_name" name="person[first_name]" type="text" value="John" /><br />
#
# <label for="person_last_name">Last name</label>:
- # <input id="person_last_name" name="person[last_name]" size="30" type="text" value="Smith" /><br />
+ # <input id="person_last_name" name="person[last_name]" type="text" value="Smith" /><br />
#
# <input name="commit" type="submit" value="Update Person" />
# </form>
@@ -932,20 +932,20 @@ module ActionView
# ==== Examples
#
# search_field(:user, :name)
- # # => <input id="user_name" name="user[name]" size="30" type="search" />
+ # # => <input id="user_name" name="user[name]" type="search" />
# search_field(:user, :name, :autosave => false)
- # # => <input autosave="false" id="user_name" name="user[name]" size="30" type="search" />
+ # # => <input autosave="false" id="user_name" name="user[name]" type="search" />
# search_field(:user, :name, :results => 3)
- # # => <input id="user_name" name="user[name]" results="3" size="30" type="search" />
+ # # => <input id="user_name" name="user[name]" results="3" type="search" />
# # Assume request.host returns "www.example.com"
# search_field(:user, :name, :autosave => true)
- # # => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" size="30" type="search" />
+ # # => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" type="search" />
# search_field(:user, :name, :onsearch => true)
- # # => <input id="user_name" incremental="true" name="user[name]" onsearch="true" size="30" type="search" />
+ # # => <input id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
# search_field(:user, :name, :autosave => false, :onsearch => true)
- # # => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" size="30" type="search" />
+ # # => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
# search_field(:user, :name, :autosave => true, :onsearch => true)
- # # => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" size="30" type="search" />
+ # # => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" type="search" />
#
def search_field(object_name, method, options = {})
Tags::SearchField.new(object_name, method, self, options).render
@@ -954,7 +954,7 @@ module ActionView
# Returns a text_field of type "tel".
#
# telephone_field("user", "phone")
- # # => <input id="user_phone" name="user[phone]" size="30" type="tel" />
+ # # => <input id="user_phone" name="user[phone]" type="tel" />
#
def telephone_field(object_name, method, options = {})
Tags::TelField.new(object_name, method, self, options).render
@@ -982,7 +982,7 @@ module ActionView
# Returns a text_field of type "url".
#
# url_field("user", "homepage")
- # # => <input id="user_homepage" size="30" name="user[homepage]" type="url" />
+ # # => <input id="user_homepage" name="user[homepage]" type="url" />
#
def url_field(object_name, method, options = {})
Tags::UrlField.new(object_name, method, self, options).render
@@ -991,7 +991,7 @@ module ActionView
# Returns a text_field of type "email".
#
# email_field("user", "address")
- # # => <input id="user_address" size="30" name="user[address]" type="email" />
+ # # => <input id="user_address" name="user[address]" type="email" />
#
def email_field(object_name, method, options = {})
Tags::EmailField.new(object_name, method, self, options).render
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index 5be3da9b94..d61c2bbee2 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -153,6 +153,8 @@ module ActionView
# form, and parameters extraction gets the last occurrence of any repeated
# key in the query string, that works for ordinary forms.
#
+ # In case if you don't want the helper to generate this hidden field you can specify <tt>:include_blank => false</tt> option.
+ #
def select(object, method, choices, options = {}, html_options = {})
Tags::Select.new(object, method, self, choices, options, html_options).render
end
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index ac9e530f01..d88f5babb9 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -14,6 +14,8 @@ module ActionView
}
JS_ESCAPE_MAP["\342\200\250".force_encoding('UTF-8').encode!] = '&#x2028;'
+ JS_ESCAPE_MAP["\342\200\251".force_encoding('UTF-8').encode!] = '&#x2029;'
+
# Escapes carriage returns and single and double quotes for JavaScript segments.
#
@@ -22,7 +24,7 @@ module ActionView
# $('some_element').replaceWith('<%=j render 'some/element_template' %>');
def escape_javascript(javascript)
if javascript
- result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] }
+ result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] }
javascript.html_safe? ? result.html_safe : result
else
''
diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb
index 22c16de057..7c2f12d8e7 100644
--- a/actionpack/lib/action_view/helpers/tags/base.rb
+++ b/actionpack/lib/action_view/helpers/tags/base.rb
@@ -5,8 +5,6 @@ module ActionView
include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper
include FormOptionsHelper
- DEFAULT_FIELD_OPTIONS = { "size" => 30 }
-
attr_reader :object
def initialize(object_name, method_name, template_object, options = {})
@@ -124,7 +122,8 @@ module ActionView
html_options = html_options.stringify_keys
add_default_name_and_id(html_options)
select = content_tag("select", add_options(option_tags, options, value(object)), html_options)
- if html_options["multiple"]
+
+ if html_options["multiple"] && options.fetch(:include_hidden) { true }
tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select
else
select
diff --git a/actionpack/lib/action_view/helpers/tags/text_area.rb b/actionpack/lib/action_view/helpers/tags/text_area.rb
index 461a049fc2..2e48850d5c 100644
--- a/actionpack/lib/action_view/helpers/tags/text_area.rb
+++ b/actionpack/lib/action_view/helpers/tags/text_area.rb
@@ -2,10 +2,8 @@ module ActionView
module Helpers
module Tags
class TextArea < Base #:nodoc:
- DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 }
-
def render
- options = DEFAULT_TEXT_AREA_OPTIONS.merge(@options.stringify_keys)
+ options = @options.stringify_keys
add_default_name_and_id(options)
if size = options.delete("size")
diff --git a/actionpack/lib/action_view/helpers/tags/text_field.rb b/actionpack/lib/action_view/helpers/tags/text_field.rb
index ce5182d20f..024a1a8af2 100644
--- a/actionpack/lib/action_view/helpers/tags/text_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/text_field.rb
@@ -4,8 +4,7 @@ module ActionView
class TextField < Base #:nodoc:
def render
options = @options.stringify_keys
- options["size"] = options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] unless options.key?("size")
- options = DEFAULT_FIELD_OPTIONS.merge(options)
+ options["size"] = options["maxlength"] unless options.key?("size")
options["type"] ||= field_type
options["value"] = options.fetch("value"){ value_before_type_cast(object) } unless field_type == "file"
options["value"] &&= ERB::Util.html_escape(options["value"])
diff --git a/actionpack/test/abstract/abstract_controller_test.rb b/actionpack/test/abstract/abstract_controller_test.rb
index bf068aedcd..30d6a7ae14 100644
--- a/actionpack/test/abstract/abstract_controller_test.rb
+++ b/actionpack/test/abstract/abstract_controller_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'set'
module AbstractController
module Testing
@@ -254,7 +255,7 @@ module AbstractController
class TestActionMethodsReloading < ActiveSupport::TestCase
test "action_methods should be reloaded after defining a new method" do
- assert_equal ["index"], Me6.action_methods
+ assert_equal Set.new(["index"]), Me6.action_methods
end
end
diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb
index 7d0609751f..03d9873fc7 100644
--- a/actionpack/test/controller/base_test.rb
+++ b/actionpack/test/controller/base_test.rb
@@ -195,7 +195,6 @@ class UrlOptionsTest < ActionController::TestCase
match "account/overview"
end
- @controller.class.send(:include, set.url_helpers)
assert !@controller.class.action_methods.include?("account_overview_path")
end
end
diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb
index 64ed7f667f..ef795dad89 100644
--- a/actionpack/test/controller/request_forgery_protection_test.rb
+++ b/actionpack/test/controller/request_forgery_protection_test.rb
@@ -43,7 +43,7 @@ class RequestForgeryProtectionController < ActionController::Base
protect_from_forgery :only => %w(index meta)
end
-class RequestForgeryProtectionControllerUsingOldBehaviour < ActionController::Base
+class RequestForgeryProtectionControllerUsingException < ActionController::Base
include RequestForgeryProtectionActions
protect_from_forgery :only => %w(index meta)
@@ -215,7 +215,7 @@ class RequestForgeryProtectionControllerTest < ActionController::TestCase
end
end
-class RequestForgeryProtectionControllerUsingOldBehaviourTest < ActionController::TestCase
+class RequestForgeryProtectionControllerUsingExceptionTest < ActionController::TestCase
include RequestForgeryProtectionTests
def assert_blocked
assert_raises(ActionController::InvalidAuthenticityToken) do
diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb
index 36884846be..3af17f495c 100644
--- a/actionpack/test/controller/send_file_test.rb
+++ b/actionpack/test/controller/send_file_test.rb
@@ -23,10 +23,6 @@ class SendFileController < ActionController::Base
def data
send_data(file_data, options)
end
-
- def multibyte_text_data
- send_data("Кирилица\n祝您好運.", options)
- end
end
class SendFileTest < ActionController::TestCase
diff --git a/actionpack/test/template/active_model_helper_test.rb b/actionpack/test/template/active_model_helper_test.rb
index 66a7bce71e..18468ee91a 100644
--- a/actionpack/test/template/active_model_helper_test.rb
+++ b/actionpack/test/template/active_model_helper_test.rb
@@ -29,14 +29,14 @@ class ActiveModelHelperTest < ActionView::TestCase
def test_text_area_with_errors
assert_dom_equal(
- %(<div class="field_with_errors"><textarea cols="40" id="post_body" name="post[body]" rows="20">\nBack to the hill and over it again!</textarea></div>),
+ %(<div class="field_with_errors"><textarea id="post_body" name="post[body]">\nBack to the hill and over it again!</textarea></div>),
text_area("post", "body")
)
end
def test_text_field_with_errors
assert_dom_equal(
- %(<div class="field_with_errors"><input id="post_author_name" name="post[author_name]" size="30" type="text" value="" /></div>),
+ %(<div class="field_with_errors"><input id="post_author_name" name="post[author_name]" type="text" value="" /></div>),
text_field("post", "author_name")
)
end
@@ -76,7 +76,7 @@ class ActiveModelHelperTest < ActionView::TestCase
end
assert_dom_equal(
- %(<div class="field_with_errors"><input id="post_author_name" name="post[author_name]" size="30" type="text" value="" /> <span class="error">can't be empty</span></div>),
+ %(<div class="field_with_errors"><input id="post_author_name" name="post[author_name]" type="text" value="" /> <span class="error">can't be empty</span></div>),
text_field("post", "author_name")
)
ensure
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 4eed5615f6..bc42e14b8a 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -249,35 +249,35 @@ class FormHelperTest < ActionView::TestCase
end
def test_label_with_block_in_erb
- assert_equal "<label for=\"post_message\">\n Message\n <input id=\"post_message\" name=\"post[message]\" size=\"30\" type=\"text\" />\n</label>", view.render("test/label_with_block")
+ assert_equal "<label for=\"post_message\">\n Message\n <input id=\"post_message\" name=\"post[message]\" type=\"text\" />\n</label>", view.render("test/label_with_block")
end
def test_text_field
assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
+ '<input id="post_title" name="post[title]" type="text" value="Hello World" />', text_field("post", "title")
)
assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="password" />', password_field("post", "title")
+ '<input id="post_title" name="post[title]" type="password" />', password_field("post", "title")
)
assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title", :value => @post.title)
+ '<input id="post_title" name="post[title]" type="password" value="Hello World" />', password_field("post", "title", :value => @post.title)
)
assert_dom_equal(
- '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
+ '<input id="person_name" name="person[name]" type="password" />', password_field("person", "name")
)
end
def test_text_field_with_escapes
@post.title = "<b>Hello World</b>"
assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="text" value="&lt;b&gt;Hello World&lt;/b&gt;" />', text_field("post", "title")
+ '<input id="post_title" name="post[title]" type="text" value="&lt;b&gt;Hello World&lt;/b&gt;" />', text_field("post", "title")
)
end
def test_text_field_with_html_entities
@post.title = "The HTML Entity for & is &amp;"
assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="text" value="The HTML Entity for &amp; is &amp;amp;" />',
+ '<input id="post_title" name="post[title]" type="text" value="The HTML Entity for &amp; is &amp;amp;" />',
text_field("post", "title")
)
end
@@ -301,18 +301,18 @@ class FormHelperTest < ActionView::TestCase
end
def test_text_field_with_nil_value
- expected = '<input id="post_title" name="post[title]" size="30" type="text" />'
+ expected = '<input id="post_title" name="post[title]" type="text" />'
assert_dom_equal expected, text_field("post", "title", :value => nil)
end
def test_text_field_with_nil_name
- expected = '<input id="post_title" size="30" type="text" value="Hello World" />'
+ expected = '<input id="post_title" type="text" value="Hello World" />'
assert_dom_equal expected, text_field("post", "title", :name => nil)
end
def test_text_field_doesnt_change_param_values
object_name = 'post[]'
- expected = '<input id="post_123_title" name="post[123][title]" size="30" type="text" value="Hello World" />'
+ expected = '<input id="post_123_title" name="post[123][title]" type="text" value="Hello World" />'
assert_equal expected, text_field(object_name, "title")
assert_equal object_name, "post[]"
end
@@ -346,7 +346,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_text_field_with_custom_type
- assert_dom_equal '<input id="user_email" size="30" name="user[email]" type="email" />',
+ assert_dom_equal '<input id="user_email" name="user[email]" type="email" />',
text_field("user", "email", :type => "email")
end
@@ -474,7 +474,7 @@ class FormHelperTest < ActionView::TestCase
def test_text_area
assert_dom_equal(
- %{<textarea cols="40" id="post_body" name="post[body]" rows="20">\nBack to the hill and over it again!</textarea>},
+ %{<textarea id="post_body" name="post[body]">\nBack to the hill and over it again!</textarea>},
text_area("post", "body")
)
end
@@ -482,14 +482,14 @@ class FormHelperTest < ActionView::TestCase
def test_text_area_with_escapes
@post.body = "Back to <i>the</i> hill and over it again!"
assert_dom_equal(
- %{<textarea cols="40" id="post_body" name="post[body]" rows="20">\nBack to &lt;i&gt;the&lt;/i&gt; hill and over it again!</textarea>},
+ %{<textarea id="post_body" name="post[body]">\nBack to &lt;i&gt;the&lt;/i&gt; hill and over it again!</textarea>},
text_area("post", "body")
)
end
def test_text_area_with_alternate_value
assert_dom_equal(
- %{<textarea cols="40" id="post_body" name="post[body]" rows="20">\nTesting alternate values.</textarea>},
+ %{<textarea id="post_body" name="post[body]">\nTesting alternate values.</textarea>},
text_area("post", "body", :value => 'Testing alternate values.')
)
end
@@ -497,7 +497,7 @@ class FormHelperTest < ActionView::TestCase
def test_text_area_with_html_entities
@post.body = "The HTML Entity for & is &amp;"
assert_dom_equal(
- %{<textarea cols="40" id="post_body" name="post[body]" rows="20">\nThe HTML Entity for &amp; is &amp;amp;</textarea>},
+ %{<textarea id="post_body" name="post[body]">\nThe HTML Entity for &amp; is &amp;amp;</textarea>},
text_area("post", "body")
)
end
@@ -510,12 +510,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_search_field
- expected = %{<input id="contact_notes_query" size="30" name="contact[notes_query]" type="search" />}
+ expected = %{<input id="contact_notes_query" name="contact[notes_query]" type="search" />}
assert_dom_equal(expected, search_field("contact", "notes_query"))
end
def test_telephone_field
- expected = %{<input id="user_cell" size="30" name="user[cell]" type="tel" />}
+ expected = %{<input id="user_cell" name="user[cell]" type="tel" />}
assert_dom_equal(expected, telephone_field("user", "cell"))
end
@@ -546,12 +546,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_url_field
- expected = %{<input id="user_homepage" size="30" name="user[homepage]" type="url" />}
+ expected = %{<input id="user_homepage" name="user[homepage]" type="url" />}
assert_dom_equal(expected, url_field("user", "homepage"))
end
def test_email_field
- expected = %{<input id="user_address" size="30" name="user[address]" type="email" />}
+ expected = %{<input id="user_address" name="user[address]" type="email" />}
assert_dom_equal(expected, email_field("user", "address"))
end
@@ -571,10 +571,10 @@ class FormHelperTest < ActionView::TestCase
def test_explicit_name
assert_dom_equal(
- '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
+ '<input id="post_title" name="dont guess" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
)
assert_dom_equal(
- %{<textarea cols="40" id="post_body" name="really!" rows="20">\nBack to the hill and over it again!</textarea>},
+ %{<textarea id="post_body" name="really!">\nBack to the hill and over it again!</textarea>},
text_area("post", "body", "name" => "really!")
)
assert_dom_equal(
@@ -591,10 +591,10 @@ class FormHelperTest < ActionView::TestCase
def test_explicit_id
assert_dom_equal(
- '<input id="dont guess" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
+ '<input id="dont guess" name="post[title]" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
)
assert_dom_equal(
- %{<textarea cols="40" id="really!" name="post[body]" rows="20">\nBack to the hill and over it again!</textarea>},
+ %{<textarea id="really!" name="post[body]">\nBack to the hill and over it again!</textarea>},
text_area("post", "body", "id" => "really!")
)
assert_dom_equal(
@@ -611,10 +611,10 @@ class FormHelperTest < ActionView::TestCase
def test_nil_id
assert_dom_equal(
- '<input name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => nil)
+ '<input name="post[title]" type="text" value="Hello World" />', text_field("post", "title", "id" => nil)
)
assert_dom_equal(
- %{<textarea cols="40" name="post[body]" rows="20">\nBack to the hill and over it again!</textarea>},
+ %{<textarea name="post[body]">\nBack to the hill and over it again!</textarea>},
text_area("post", "body", "id" => nil)
)
assert_dom_equal(
@@ -641,11 +641,11 @@ class FormHelperTest < ActionView::TestCase
def test_index
assert_dom_equal(
- '<input name="post[5][title]" size="30" id="post_5_title" type="text" value="Hello World" />',
+ '<input name="post[5][title]" id="post_5_title" type="text" value="Hello World" />',
text_field("post", "title", "index" => 5)
)
assert_dom_equal(
- %{<textarea cols="40" name="post[5][body]" id="post_5_body" rows="20">\nBack to the hill and over it again!</textarea>},
+ %{<textarea name="post[5][body]" id="post_5_body">\nBack to the hill and over it again!</textarea>},
text_area("post", "body", "index" => 5)
)
assert_dom_equal(
@@ -668,11 +668,11 @@ class FormHelperTest < ActionView::TestCase
def test_index_with_nil_id
assert_dom_equal(
- '<input name="post[5][title]" size="30" type="text" value="Hello World" />',
+ '<input name="post[5][title]" type="text" value="Hello World" />',
text_field("post", "title", "index" => 5, 'id' => nil)
)
assert_dom_equal(
- %{<textarea cols="40" name="post[5][body]" rows="20">\nBack to the hill and over it again!</textarea>},
+ %{<textarea name="post[5][body]">\nBack to the hill and over it again!</textarea>},
text_area("post", "body", "index" => 5, 'id' => nil)
)
assert_dom_equal(
@@ -700,10 +700,10 @@ class FormHelperTest < ActionView::TestCase
label("post[]", "title")
)
assert_dom_equal(
- "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
+ "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
)
assert_dom_equal(
- "<textarea cols=\"40\" id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\" rows=\"20\">\nBack to the hill and over it again!</textarea>",
+ "<textarea id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\">\nBack to the hill and over it again!</textarea>",
text_area("post[]", "body")
)
assert_dom_equal(
@@ -722,11 +722,11 @@ class FormHelperTest < ActionView::TestCase
def test_auto_index_with_nil_id
pid = 123
assert_dom_equal(
- "<input name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />",
+ "<input name=\"post[#{pid}][title]\" type=\"text\" value=\"Hello World\" />",
text_field("post[]","title", :id => nil)
)
assert_dom_equal(
- "<textarea cols=\"40\" name=\"post[#{pid}][body]\" rows=\"20\">\nBack to the hill and over it again!</textarea>",
+ "<textarea name=\"post[#{pid}][body]\">\nBack to the hill and over it again!</textarea>",
text_area("post[]", "body", :id => nil)
)
assert_dom_equal(
@@ -760,8 +760,8 @@ class FormHelperTest < ActionView::TestCase
expected = whole_form("/posts/123", "create-post" , "edit_post", :method => 'patch') do
"<label for='post_title'>The Title</label>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='commit' type='submit' value='Create post' />" +
@@ -859,7 +859,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/posts/44", "edit_post_44" , "edit_post", :method => 'patch') do
- "<input name='post[title]' size='30' type='text' id='post_title' value='And his name will be forty and four.' />" +
+ "<input name='post[title]' type='text' id='post_title' value='And his name will be forty and four.' />" +
"<input name='commit' type='submit' value='Edit post' />"
end
@@ -877,8 +877,8 @@ class FormHelperTest < ActionView::TestCase
expected = whole_form("/posts/123", "create-post", "edit_other_name", :method => 'patch') do
"<label for='other_name_title' class='post_title'>Title</label>" +
- "<input name='other_name[title]' size='30' id='other_name_title' value='Hello World' type='text' />" +
- "<textarea name='other_name[body]' id='other_name_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='other_name[title]' id='other_name_title' value='Hello World' type='text' />" +
+ "<textarea name='other_name[body]' id='other_name_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='other_name[secret]' value='0' type='hidden' />" +
"<input name='other_name[secret]' checked='checked' id='other_name_secret' value='1' type='checkbox' />" +
"<input name='commit' value='Create post' type='submit' />"
@@ -895,8 +895,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/", "create-post", "edit_post", "delete") do
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
end
@@ -912,8 +912,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/", "create-post", "edit_post", "delete") do
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
end
@@ -929,7 +929,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/search", "search-post", "new_post", "get") do
- "<input name='post[title]' size='30' type='search' id='post_title' />"
+ "<input name='post[title]' type='search' id='post_title' />"
end
assert_dom_equal expected, output_buffer
@@ -943,8 +943,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/", "create-post", "edit_post", :method => 'patch', :remote => true) do
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
end
@@ -960,8 +960,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/", "create-post", "edit_post", :method => 'patch', :remote => true) do
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
end
@@ -979,8 +979,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/posts", 'new_post', 'new_post', :remote => true) do
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
end
@@ -996,8 +996,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/", "create-post") do
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
end
@@ -1015,8 +1015,8 @@ class FormHelperTest < ActionView::TestCase
expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
"<label for='post_123_title'>Title</label>" +
- "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
- "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[123][title]' type='text' id='post_123_title' value='Hello World' />" +
+ "<textarea name='post[123][body]' id='post_123_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[123][secret]' type='hidden' value='0' />" +
"<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
end
@@ -1032,8 +1032,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
- "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
- "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[][title]' type='text' id='post__title' value='Hello World' />" +
+ "<textarea name='post[][body]' id='post__body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[][secret]' type='hidden' value='0' />" +
"<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
end
@@ -1049,8 +1049,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'namespace_edit_post_123', 'edit_post', 'patch') do
- "<input name='post[title]' size='30' type='text' id='namespace_post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='namespace_post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='namespace_post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='namespace_post_secret' value='1' />"
end
@@ -1066,7 +1066,7 @@ class FormHelperTest < ActionView::TestCase
expected = whole_form('/posts/123', 'namespace_edit_post_123', 'edit_post', 'patch') do
"<label for='namespace_post_title'>Title</label>" +
- "<input name='post[title]' size='30' type='text' id='namespace_post_title' value='Hello World' />"
+ "<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />"
end
assert_dom_equal expected, output_buffer
@@ -1080,7 +1080,7 @@ class FormHelperTest < ActionView::TestCase
expected_1 = whole_form('/posts/123', 'namespace_1_edit_post_123', 'edit_post', 'patch') do
"<label for='namespace_1_post_title'>Title</label>" +
- "<input name='post[title]' size='30' type='text' id='namespace_1_post_title' value='Hello World' />"
+ "<input name='post[title]' type='text' id='namespace_1_post_title' value='Hello World' />"
end
assert_dom_equal expected_1, output_buffer
@@ -1092,7 +1092,7 @@ class FormHelperTest < ActionView::TestCase
expected_2 = whole_form('/posts/123', 'namespace_2_edit_post_123', 'edit_post', 'patch') do
"<label for='namespace_2_post_title'>Title</label>" +
- "<input name='post[title]' size='30' type='text' id='namespace_2_post_title' value='Hello World' />"
+ "<input name='post[title]' type='text' id='namespace_2_post_title' value='Hello World' />"
end
assert_dom_equal expected_2, output_buffer
@@ -1109,9 +1109,9 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'namespace_edit_post_123', 'edit_post', 'patch') do
- "<input name='post[title]' size='30' type='text' id='namespace_post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='namespace_post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
- "<input name='post[comment][body]' size='30' type='text' id='namespace_post_comment_body' value='Hello World' />"
+ "<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='namespace_post_body'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[comment][body]' type='text' id='namespace_post_comment_body' value='Hello World' />"
end
assert_dom_equal expected, output_buffer
@@ -1192,7 +1192,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- "<input name='post[comment][body]' size='30' type='text' id='post_comment_body' value='Hello World' />"
+ "<input name='post[comment][body]' type='text' id='post_comment_body' value='Hello World' />"
end
assert_dom_equal expected, output_buffer
@@ -1207,8 +1207,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
- "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
- "<input name='post[123][comment][][name]' size='30' type='text' id='post_123_comment__name' value='new comment' />"
+ "<input name='post[123][title]' type='text' id='post_123_title' value='Hello World' />" +
+ "<input name='post[123][comment][][name]' type='text' id='post_123_comment__name' value='new comment' />"
end
assert_dom_equal expected, output_buffer
@@ -1223,8 +1223,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'patch') do
- "<input name='post[1][title]' size='30' type='text' id='post_1_title' value='Hello World' />" +
- "<input name='post[1][comment][1][name]' size='30' type='text' id='post_1_comment_1_name' value='new comment' />"
+ "<input name='post[1][title]' type='text' id='post_1_title' value='Hello World' />" +
+ "<input name='post[1][comment][1][name]' type='text' id='post_1_comment_1_name' value='new comment' />"
end
assert_dom_equal expected, output_buffer
@@ -1238,7 +1238,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'patch') do
- "<input name='post[1][comment][title]' size='30' type='text' id='post_1_comment_title' value='Hello World' />"
+ "<input name='post[1][comment][title]' type='text' id='post_1_comment_title' value='Hello World' />"
end
assert_dom_equal expected, output_buffer
@@ -1252,7 +1252,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'patch') do
- "<input name='post[1][comment][5][title]' size='30' type='text' id='post_1_comment_5_title' value='Hello World' />"
+ "<input name='post[1][comment][5][title]' type='text' id='post_1_comment_5_title' value='Hello World' />"
end
assert_dom_equal expected, output_buffer
@@ -1266,7 +1266,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
- "<input name='post[123][comment][title]' size='30' type='text' id='post_123_comment_title' value='Hello World' />"
+ "<input name='post[123][comment][title]' type='text' id='post_123_comment_title' value='Hello World' />"
end
assert_dom_equal expected, output_buffer
@@ -1294,7 +1294,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
- "<input name='post[123][comment][123][title]' size='30' type='text' id='post_123_comment_123_title' value='Hello World' />"
+ "<input name='post[123][comment][123][title]' type='text' id='post_123_comment_123_title' value='Hello World' />"
end
assert_dom_equal expected, output_buffer
@@ -1314,9 +1314,9 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
- "<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />"
+ "<input name='post[123][comment][5][title]' type='text' id='post_123_comment_5_title' value='Hello World' />"
end + whole_form('/posts/123', 'edit_post', 'edit_post', 'patch') do
- "<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />"
+ "<input name='post[1][comment][123][title]' type='text' id='post_1_comment_123_title' value='Hello World' />"
end
assert_dom_equal expected, output_buffer
@@ -1333,8 +1333,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="new author" />'
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="new author" />'
end
assert_dom_equal expected, output_buffer
@@ -1360,8 +1360,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />'
end
@@ -1379,8 +1379,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />'
end
@@ -1398,8 +1398,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />'
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />'
end
assert_dom_equal expected, output_buffer
@@ -1416,8 +1416,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />'
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />'
end
assert_dom_equal expected, output_buffer
@@ -1434,8 +1434,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />'
end
@@ -1454,9 +1454,9 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />'
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />'
end
assert_dom_equal expected, output_buffer
@@ -1475,10 +1475,10 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
end
@@ -1502,11 +1502,11 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />'
end
assert_dom_equal expected, output_buffer
@@ -1529,10 +1529,10 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />'
end
assert_dom_equal expected, output_buffer
@@ -1555,11 +1555,11 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />'
end
assert_dom_equal expected, output_buffer
@@ -1578,10 +1578,10 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
end
@@ -1602,11 +1602,11 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />'
end
assert_dom_equal expected, output_buffer
@@ -1625,9 +1625,9 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="new comment" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />'
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="new comment" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="new comment" />'
end
assert_dom_equal expected, output_buffer
@@ -1646,10 +1646,10 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />'
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="new comment" />'
end
assert_dom_equal expected, output_buffer
@@ -1664,7 +1664,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />'
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />'
end
assert_dom_equal expected, output_buffer
@@ -1681,10 +1681,10 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
end
@@ -1702,10 +1702,10 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
end
@@ -1724,10 +1724,10 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
end
@@ -1747,10 +1747,10 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
+ '<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />'
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="new comment" />'
end
assert_dom_equal expected, output_buffer
@@ -1767,7 +1767,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
+ '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />'
end
@@ -1803,16 +1803,16 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
- '<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="commentrelevance #314" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' +
+ '<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" type="text" value="commentrelevance #314" />' +
'<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
- '<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" size="30" type="text" value="tag #123" />' +
- '<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #3141" />' +
+ '<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" type="text" value="tag #123" />' +
+ '<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" type="text" value="tagrelevance #3141" />' +
'<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
'<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
- '<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" size="30" type="text" value="tag #456" />' +
- '<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #31415" />' +
+ '<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" type="text" value="tag #456" />' +
+ '<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" type="text" value="tagrelevance #31415" />' +
'<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
'<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />'
end
@@ -1830,7 +1830,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="hash backed author" />'
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="hash backed author" />'
end
assert_dom_equal expected, output_buffer
@@ -1844,8 +1844,8 @@ class FormHelperTest < ActionView::TestCase
end
expected =
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
@@ -1860,8 +1860,8 @@ class FormHelperTest < ActionView::TestCase
end
expected =
- "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
- "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[123][title]' type='text' id='post_123_title' value='Hello World' />" +
+ "<textarea name='post[123][body]' id='post_123_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[123][secret]' type='hidden' value='0' />" +
"<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
@@ -1876,8 +1876,8 @@ class FormHelperTest < ActionView::TestCase
end
expected =
- "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
- "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[][title]' type='text' id='post__title' value='Hello World' />" +
+ "<textarea name='post[][body]' id='post__body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[][secret]' type='hidden' value='0' />" +
"<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
@@ -1892,8 +1892,8 @@ class FormHelperTest < ActionView::TestCase
end
expected =
- "<input name='post[abc][title]' size='30' type='text' id='post_abc_title' value='Hello World' />" +
- "<textarea name='post[abc][body]' id='post_abc_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[abc][title]' type='text' id='post_abc_title' value='Hello World' />" +
+ "<textarea name='post[abc][body]' id='post_abc_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[abc][secret]' type='hidden' value='0' />" +
"<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
@@ -1908,8 +1908,8 @@ class FormHelperTest < ActionView::TestCase
end
expected =
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
@@ -1924,8 +1924,8 @@ class FormHelperTest < ActionView::TestCase
end
expected =
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
@@ -1939,7 +1939,7 @@ class FormHelperTest < ActionView::TestCase
end
assert_dom_equal "<label for=\"author_post_title\">Title</label>" +
- "<input name='author[post][title]' size='30' type='text' id='author_post_title' value='Hello World' />",
+ "<input name='author[post][title]' type='text' id='author_post_title' value='Hello World' />",
output_buffer
end
@@ -1950,7 +1950,7 @@ class FormHelperTest < ActionView::TestCase
end
assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" +
- "<input name='author[post][1][title]' size='30' type='text' id='author_post_1_title' value='Hello World' />",
+ "<input name='author[post][1][title]' type='text' id='author_post_1_title' value='Hello World' />",
output_buffer
end
@@ -1969,8 +1969,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'create-post', 'edit_post', :method => 'patch') do
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='parent_post[secret]' type='hidden' value='0' />" +
"<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />"
end
@@ -1989,9 +1989,9 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'create-post', 'edit_post', :method => 'patch') do
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea>" +
- "<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />"
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
+ "<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' />"
end
assert_dom_equal expected, output_buffer
@@ -2005,7 +2005,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'patch') do
- "<input name='post[category][name]' type='text' size='30' id='post_category_name' />"
+ "<input name='post[category][name]' type='text' id='post_category_name' />"
end
assert_dom_equal expected, output_buffer
@@ -2029,8 +2029,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea><br/>" +
+ "<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><br/>" +
+ "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
end
@@ -2048,8 +2048,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea><br/>" +
+ "<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><br/>" +
+ "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
end
@@ -2066,8 +2066,8 @@ class FormHelperTest < ActionView::TestCase
end
expected =
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>\nBack to the hill and over it again!</textarea><br/>" +
+ "<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><br/>" +
+ "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
assert_dom_equal expected, output_buffer
diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb
index 606d454cb3..2c0da8473a 100644
--- a/actionpack/test/template/form_options_helper_test.rb
+++ b/actionpack/test/template/form_options_helper_test.rb
@@ -529,6 +529,14 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_select_with_multiple_and_without_hidden_input
+ output_buffer = select(:post, :category, "", {:include_hidden => false}, :multiple => true)
+ assert_dom_equal(
+ "<select multiple=\"multiple\" id=\"post_category\" name=\"post[category][]\"></select>",
+ output_buffer
+ )
+ end
+
def test_select_with_multiple_and_disabled_to_add_disabled_hidden_input
output_buffer = select(:post, :category, "", {}, :multiple => true, :disabled => true)
assert_dom_equal(
diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb
index 9441bd6b38..64898f7ad1 100644
--- a/actionpack/test/template/javascript_helper_test.rb
+++ b/actionpack/test/template/javascript_helper_test.rb
@@ -28,6 +28,8 @@ class JavaScriptHelperTest < ActionView::TestCase
assert_equal %(backslash\\\\test), escape_javascript( %(backslash\\test) )
assert_equal %(dont <\\/close> tags), escape_javascript(%(dont </close> tags))
assert_equal %(unicode &#x2028; newline), escape_javascript(%(unicode \342\200\250 newline).force_encoding('UTF-8').encode!)
+ assert_equal %(unicode &#x2029; newline), escape_javascript(%(unicode \342\200\251 newline).force_encoding('UTF-8').encode!)
+
assert_equal %(dont <\\/close> tags), j(%(dont </close> tags))
end
diff --git a/actionpack/test/template/test_case_test.rb b/actionpack/test/template/test_case_test.rb
index 37858c1ba2..f2ed2ec609 100644
--- a/actionpack/test/template/test_case_test.rb
+++ b/actionpack/test/template/test_case_test.rb
@@ -277,6 +277,12 @@ module ActionView
end
class RenderTemplateTest < ActionView::TestCase
+ test "supports specifying templates with a Regexp" do
+ controller.controller_path = "fun"
+ render(:template => "fun/games/hello_world")
+ assert_template %r{\Afun/games/hello_world\Z}
+ end
+
test "supports specifying partials" do
controller.controller_path = "test"
render(:template => "test/calling_partial_with_layout")
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index 42adbec8b9..c6d8eae46c 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -1,13 +1,22 @@
+## Rails 4.0.0 (unreleased) ##
+
* Added ActiveModel::Model, a mixin to make Ruby objects work with AP out of box *Guillermo Iguaran*
* `AM::Errors#to_json`: support `:full_messages` parameter *Bogdan Gusiev*
* Trim down Active Model API by removing `valid?` and `errors.full_messages` *José Valim*
+
+## Rails 3.2.2 (March 1, 2012) ##
+
+* No changes.
+
+
## Rails 3.2.1 (January 26, 2012) ##
* No changes.
+
## Rails 3.2.0 (January 20, 2012) ##
* Deprecated `define_attr_method` in `ActiveModel::AttributeMethods`, because this only existed to
@@ -23,14 +32,17 @@
* Provide mass_assignment_sanitizer as an easy API to replace the sanitizer behavior. Also support both :logger (default) and :strict sanitizer behavior *Bogdan Gusiev*
+
## Rails 3.1.3 (November 20, 2011) ##
* No changes
+
## Rails 3.1.2 (November 18, 2011) ##
* No changes
+
## Rails 3.1.1 (October 7, 2011) ##
* Remove hard dependency on bcrypt-ruby to avoid make ActiveModel dependent on a binary library.
@@ -40,6 +52,7 @@
See GH #2687. *Guillermo Iguaran*
+
## Rails 3.1.0 (August 30, 2011) ##
* Alternate I18n namespace lookup is no longer supported.
diff --git a/activemodel/lib/active_model/conversion.rb b/activemodel/lib/active_model/conversion.rb
index c7c805f1a2..d7f30f0920 100644
--- a/activemodel/lib/active_model/conversion.rb
+++ b/activemodel/lib/active_model/conversion.rb
@@ -21,7 +21,7 @@ module ActiveModel
# cm.to_model == self # => true
# cm.to_key # => nil
# cm.to_param # => nil
- # cm.to_path # => "contact_messages/contact_message"
+ # cm.to_partial_path # => "contact_messages/contact_message"
#
module Conversion
extend ActiveSupport::Concern
@@ -57,7 +57,7 @@ module ActiveModel
end
module ClassMethods #:nodoc:
- # Provide a class level cache for the to_path. This is an
+ # Provide a class level cache for #to_partial_path. This is an
# internal method and should not be accessed directly.
def _to_partial_path #:nodoc:
@_to_partial_path ||= begin
diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb
index 755e54efcd..fd0bc4e8e9 100644
--- a/activemodel/lib/active_model/naming.rb
+++ b/activemodel/lib/active_model/naming.rb
@@ -2,6 +2,7 @@ require 'active_support/inflector'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/module/introspection'
require 'active_support/core_ext/module/deprecation'
+require 'active_support/core_ext/object/blank'
module ActiveModel
class Name < String
diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb
index 51f078e662..4323ee1e09 100644
--- a/activemodel/lib/active_model/serialization.rb
+++ b/activemodel/lib/active_model/serialization.rb
@@ -1,7 +1,5 @@
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/slice'
-require 'active_support/core_ext/array/wrap'
-
module ActiveModel
# == Active Model Serialization
@@ -11,7 +9,6 @@ module ActiveModel
# A minimal implementation could be:
#
# class Person
- #
# include ActiveModel::Serialization
#
# attr_accessor :name
@@ -19,7 +16,6 @@ module ActiveModel
# def attributes
# {'name' => nil}
# end
- #
# end
#
# Which would provide you with:
@@ -43,7 +39,6 @@ module ActiveModel
# So a minimal implementation including XML and JSON would be:
#
# class Person
- #
# include ActiveModel::Serializers::JSON
# include ActiveModel::Serializers::Xml
#
@@ -52,7 +47,6 @@ module ActiveModel
# def attributes
# {'name' => nil}
# end
- #
# end
#
# Which would provide you with:
@@ -88,7 +82,7 @@ module ActiveModel
method_names.each { |n| hash[n.to_s] = send(n) }
serializable_add_includes(options) do |association, records, opts|
- hash[association] = if records.is_a?(Enumerable)
+ hash[association.to_s] = if records.is_a?(Enumerable)
records.map { |a| a.serializable_hash(opts) }
else
records.serializable_hash(opts)
@@ -126,13 +120,13 @@ module ActiveModel
# +records+ - the association record(s) to be serialized
# +opts+ - options for the association records
def serializable_add_includes(options = {}) #:nodoc:
- return unless include = options[:include]
+ return unless includes = options[:include]
- unless include.is_a?(Hash)
- include = Hash[Array.wrap(include).map { |n| n.is_a?(Hash) ? n.to_a.first : [n, {}] }]
+ unless includes.is_a?(Hash)
+ includes = Hash[Array(includes).map { |n| n.is_a?(Hash) ? n.to_a.first : [n, {}] }]
end
- include.each do |association, opts|
+ includes.each do |association, opts|
if records = send(association)
yield association, records, opts
end
diff --git a/activemodel/test/cases/conversion_test.rb b/activemodel/test/cases/conversion_test.rb
index 24552bcaf2..d679ad41aa 100644
--- a/activemodel/test/cases/conversion_test.rb
+++ b/activemodel/test/cases/conversion_test.rb
@@ -24,7 +24,7 @@ class ConversionTest < ActiveModel::TestCase
assert_equal "1", Contact.new(:id => 1).to_param
end
- test "to_path default implementation returns a string giving a relative path" do
+ test "to_partial_path default implementation returns a string giving a relative path" do
assert_equal "contacts/contact", Contact.new.to_partial_path
assert_equal "helicopters/helicopter", Helicopter.new.to_partial_path,
"ActiveModel::Conversion#to_partial_path caching should be class-specific"
diff --git a/activemodel/test/cases/serialization_test.rb b/activemodel/test/cases/serialization_test.rb
index 3b201a70f5..66b18d65e5 100644
--- a/activemodel/test/cases/serialization_test.rb
+++ b/activemodel/test/cases/serialization_test.rb
@@ -88,62 +88,62 @@ class SerializationTest < ActiveModel::TestCase
def test_include_option_with_singular_association
expected = {"name"=>"David", "gender"=>"male", "email"=>"david@example.com",
- :address=>{"street"=>"123 Lane", "city"=>"Springfield", "state"=>"CA", "zip"=>11111}}
+ "address"=>{"street"=>"123 Lane", "city"=>"Springfield", "state"=>"CA", "zip"=>11111}}
assert_equal expected, @user.serializable_hash(:include => :address)
end
def test_include_option_with_plural_association
expected = {"email"=>"david@example.com", "gender"=>"male", "name"=>"David",
- :friends=>[{"name"=>'Joe', "email"=>'joe@example.com', "gender"=>'male'},
+ "friends"=>[{"name"=>'Joe', "email"=>'joe@example.com', "gender"=>'male'},
{"name"=>'Sue', "email"=>'sue@example.com', "gender"=>'female'}]}
assert_equal expected, @user.serializable_hash(:include => :friends)
end
def test_include_option_with_empty_association
@user.friends = []
- expected = {"email"=>"david@example.com", "gender"=>"male", "name"=>"David", :friends=>[]}
+ expected = {"email"=>"david@example.com", "gender"=>"male", "name"=>"David", "friends"=>[]}
assert_equal expected, @user.serializable_hash(:include => :friends)
end
def test_multiple_includes
expected = {"email"=>"david@example.com", "gender"=>"male", "name"=>"David",
- :address=>{"street"=>"123 Lane", "city"=>"Springfield", "state"=>"CA", "zip"=>11111},
- :friends=>[{"name"=>'Joe', "email"=>'joe@example.com', "gender"=>'male'},
+ "address"=>{"street"=>"123 Lane", "city"=>"Springfield", "state"=>"CA", "zip"=>11111},
+ "friends"=>[{"name"=>'Joe', "email"=>'joe@example.com', "gender"=>'male'},
{"name"=>'Sue', "email"=>'sue@example.com', "gender"=>'female'}]}
assert_equal expected, @user.serializable_hash(:include => [:address, :friends])
end
def test_include_with_options
expected = {"email"=>"david@example.com", "gender"=>"male", "name"=>"David",
- :address=>{"street"=>"123 Lane"}}
+ "address"=>{"street"=>"123 Lane"}}
assert_equal expected, @user.serializable_hash(:include => {:address => {:only => "street"}})
end
def test_nested_include
@user.friends.first.friends = [@user]
expected = {"email"=>"david@example.com", "gender"=>"male", "name"=>"David",
- :friends=>[{"name"=>'Joe', "email"=>'joe@example.com', "gender"=>'male',
- :friends => [{"email"=>"david@example.com", "gender"=>"male", "name"=>"David"}]},
- {"name"=>'Sue', "email"=>'sue@example.com', "gender"=>'female', :friends => []}]}
+ "friends"=>[{"name"=>'Joe', "email"=>'joe@example.com', "gender"=>'male',
+ "friends"=> [{"email"=>"david@example.com", "gender"=>"male", "name"=>"David"}]},
+ {"name"=>'Sue', "email"=>'sue@example.com', "gender"=>'female', "friends"=> []}]}
assert_equal expected, @user.serializable_hash(:include => {:friends => {:include => :friends}})
end
def test_only_include
- expected = {"name"=>"David", :friends => [{"name" => "Joe"}, {"name" => "Sue"}]}
+ expected = {"name"=>"David", "friends" => [{"name" => "Joe"}, {"name" => "Sue"}]}
assert_equal expected, @user.serializable_hash(:only => :name, :include => {:friends => {:only => :name}})
end
def test_except_include
expected = {"name"=>"David", "email"=>"david@example.com",
- :friends => [{"name" => 'Joe', "email" => 'joe@example.com'},
+ "friends"=> [{"name" => 'Joe', "email" => 'joe@example.com'},
{"name" => "Sue", "email" => 'sue@example.com'}]}
assert_equal expected, @user.serializable_hash(:except => :gender, :include => {:friends => {:except => :gender}})
end
def test_multiple_includes_with_options
expected = {"email"=>"david@example.com", "gender"=>"male", "name"=>"David",
- :address=>{"street"=>"123 Lane"},
- :friends=>[{"name"=>'Joe', "email"=>'joe@example.com', "gender"=>'male'},
+ "address"=>{"street"=>"123 Lane"},
+ "friends"=>[{"name"=>'Joe', "email"=>'joe@example.com', "gender"=>'male'},
{"name"=>'Sue', "email"=>'sue@example.com', "gender"=>'female'}]}
assert_equal expected, @user.serializable_hash(:include => [{:address => {:only => "street"}}, :friends])
end
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index d7823855a3..6fd86b1f32 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -153,6 +153,28 @@
* PostgreSQL hstore types are automatically deserialized from the database.
+## Rails 3.2.3 (unreleased) ##
+
+* Added find_or_create_by_{attribute}! dynamic method. *Andrew White*
+
+* Whitelist all attribute assignment by default. Change the default for newly generated applications to whitelist all attribute assignment. Also update the generated model classes so users are reminded of the importance of attr_accessible. *NZKoz*
+
+* Update ActiveRecord::AttributeMethods#attribute_present? to return false for empty strings. *Jacobkg*
+
+* Fix associations when using per class databases. *larskanis*
+
+* Revert setting NOT NULL constraints in add_timestamps *fxn*
+
+* Fix mysql to use proper text types. Fixes #3931. *kennyj*
+
+* Fix #5069 - Protect foreign key from mass assignment through association builder. *byroot*
+
+
+## Rails 3.2.2 (March 1, 2012) ##
+
+* No changes.
+
+
## Rails 3.2.1 (January 26, 2012) ##
* The threshold for auto EXPLAIN is ignored if there's no logger. *fxn*
@@ -343,6 +365,7 @@
*Aaron Christy*
+
## Rails 3.1.4 (March 1, 2012) ##
* Fix a custom primary key regression *GH 3987*
@@ -370,6 +393,7 @@
*Julius de Bruijn*
+
### Rails 3.1.3 (November 20, 2011) ##
* Perf fix: If we're deleting all records in an association, don't add a IN(..) clause
@@ -383,6 +407,7 @@
*Christos Zisopoulos and Kenny J*
+
### Rails 3.1.2 (November 18, 2011) ##
* Fix bug with PostgreSQLAdapter#indexes. When the search path has multiple schemas, spaces
@@ -430,6 +455,7 @@
*Kenny J*
+
## Rails 3.1.1 (October 7, 2011) ##
* Add deprecation for the preload_associations method. Fixes #3022.
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index b2136605e1..da4c311bce 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -544,7 +544,7 @@ module ActiveRecord
# If using a custom finder_sql, #find scans the entire collection.
def find_by_scan(*args)
expects_array = args.first.kind_of?(Array)
- ids = args.flatten.compact.uniq.map { |arg| arg.to_i }
+ ids = args.flatten.compact.map{ |arg| arg.to_i }.uniq
if ids.size == 1
id = ids.first
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 93c243e7b1..bebf6a1a05 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -214,37 +214,64 @@ module ActiveRecord
value
end
- # Returns a copy of the attributes hash where all the values have been safely quoted for use in
- # an Arel insert/update method.
- def arel_attributes_values(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
- attrs = {}
- klass = self.class
- arel_table = klass.arel_table
+ def arel_attributes_with_values_for_create(pk_attribute_allowed)
+ arel_attributes_with_values(attributes_for_create(pk_attribute_allowed))
+ end
- attribute_names.each do |name|
- if (column = column_for_attribute(name)) && (include_primary_key || !column.primary)
+ def arel_attributes_with_values_for_update(attribute_names)
+ arel_attributes_with_values(attributes_for_update(attribute_names))
+ end
- if include_readonly_attributes || !self.class.readonly_attributes.include?(name)
+ def attribute_method?(attr_name)
+ defined?(@attributes) && @attributes.include?(attr_name)
+ end
- value = if klass.serialized_attributes.include?(name)
- @attributes[name].serialized_value
- else
- # FIXME: we need @attributes to be used consistently.
- # If the values stored in @attributes were already type
- # casted, this code could be simplified
- read_attribute(name)
- end
+ private
- attrs[arel_table[name]] = value
- end
- end
- end
+ # Returns a Hash of the Arel::Attributes and attribute values that have been
+ # type casted for use in an Arel insert/update method.
+ def arel_attributes_with_values(attribute_names)
+ attrs = {}
+ arel_table = self.class.arel_table
+ attribute_names.each do |name|
+ attrs[arel_table[name]] = typecasted_attribute_value(name)
+ end
attrs
end
- def attribute_method?(attr_name)
- defined?(@attributes) && @attributes.include?(attr_name)
+ # Filters the primary keys and readonly attributes from the attribute names.
+ def attributes_for_update(attribute_names)
+ attribute_names.select do |name|
+ column_for_attribute(name) && !pk_attribute?(name) && !readonly_attribute?(name)
+ end
+ end
+
+ # Filters out the primary keys, from the attribute names, when the primary
+ # key is to be generated (e.g. the id attribute has no value).
+ def attributes_for_create(pk_attribute_allowed)
+ @attributes.keys.select do |name|
+ column_for_attribute(name) && (pk_attribute_allowed || !pk_attribute?(name))
+ end
+ end
+
+ def readonly_attribute?(name)
+ self.class.readonly_attributes.include?(name)
+ end
+
+ def pk_attribute?(name)
+ column_for_attribute(name).primary
+ end
+
+ def typecasted_attribute_value(name)
+ if self.class.serialized_attributes.include?(name)
+ @attributes[name].serialized_value
+ else
+ # FIXME: we need @attributes to be used consistently.
+ # If the values stored in @attributes were already typecasted, this code
+ # could be simplified
+ read_attribute(name)
+ end
end
end
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index d4d0220fb7..d25a821688 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -201,6 +201,9 @@ module ActiveRecord #:nodoc:
# # Now 'Bob' exist and is an 'admin'
# User.find_or_create_by_name('Bob', :age => 40) { |u| u.admin = true }
#
+ # Adding an exclamation point (!) on to the end of <tt>find_or_create_by_</tt> will
+ # raise an <tt>ActiveRecord::RecordInvalid</tt> error if the new record is invalid.
+ #
# Use the <tt>find_or_initialize_by_</tt> finder if you want to return a new record without
# saving it first. Protected attributes won't be set unless they are given in a block.
#
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index 37a9d216df..561e48d52e 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -128,10 +128,11 @@ module ActiveRecord
@reserved_connections[current_connection_id] ||= checkout
end
- # Check to see if there is an active connection in this connection
- # pool.
+ # Is there an open connection that is being used for the current thread?
def active_connection?
- active_connections.any?
+ @reserved_connections.fetch(current_connection_id) {
+ return false
+ }.in_use?
end
# Signal that the thread is finished with the current connection.
@@ -185,8 +186,9 @@ module ActiveRecord
end
def clear_stale_cached_connections! # :nodoc:
+ reap
end
- deprecate :clear_stale_cached_connections!
+ deprecate :clear_stale_cached_connections! => "Please use #reap instead"
# Check-out a database connection from the pool, indicating that you want
# to use it. You should call #checkin when you no longer need this.
@@ -233,6 +235,8 @@ module ActiveRecord
conn.run_callbacks :checkin do
conn.expire
end
+
+ release conn
end
end
@@ -244,10 +248,7 @@ module ActiveRecord
# FIXME: we might want to store the key on the connection so that removing
# from the reserved hash will be a little easier.
- thread_id = @reserved_connections.keys.find { |k|
- @reserved_connections[k] == conn
- }
- @reserved_connections.delete thread_id if thread_id
+ release conn
end
end
@@ -265,6 +266,20 @@ module ActiveRecord
private
+ def release(conn)
+ thread_id = nil
+
+ if @reserved_connections[current_connection_id] == conn
+ thread_id = current_connection_id
+ else
+ thread_id = @reserved_connections.keys.find { |k|
+ @reserved_connections[k] == conn
+ }
+ end
+
+ @reserved_connections.delete thread_id if thread_id
+ end
+
def new_connection
ActiveRecord::Base.send(spec.adapter_method, spec.config)
end
@@ -288,10 +303,6 @@ module ActiveRecord
end
c
end
-
- def active_connections
- @connections.find_all { |c| c.in_use? }
- end
end
# ConnectionHandler is a collection of ConnectionPool objects. It is used
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index e75a2a1cb4..46aababfb6 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -130,7 +130,7 @@ module ActiveRecord
end
def arel_engine
- @arel_engine ||= connection_handler.connection_pools[name] ? self : active_record_super.arel_engine
+ @arel_engine ||= connection_handler.retrieve_connection_pool(self) ? self : active_record_super.arel_engine
end
private
diff --git a/activerecord/lib/active_record/dynamic_finder_match.rb b/activerecord/lib/active_record/dynamic_finder_match.rb
index 38dbbef5fc..0473d6aafc 100644
--- a/activerecord/lib/active_record/dynamic_finder_match.rb
+++ b/activerecord/lib/active_record/dynamic_finder_match.rb
@@ -7,7 +7,7 @@ module ActiveRecord
class DynamicFinderMatch
def self.match(method)
method = method.to_s
- klass = [FindBy, FindByBang, FindOrInitializeCreateBy].find do |_klass|
+ klass = klasses.find do |_klass|
_klass.matches?(method)
end
klass.new(method) if klass
@@ -17,6 +17,10 @@ module ActiveRecord
method =~ self::METHOD_PATTERN
end
+ def self.klasses
+ [FindBy, FindByBang, FindOrInitializeCreateBy, FindOrCreateByBang]
+ end
+
def initialize(method)
@finder = :first
@instantiator = nil
@@ -47,6 +51,14 @@ module ActiveRecord
arguments.size >= @attribute_names.size
end
+ def save_record?
+ @instantiator == :create
+ end
+
+ def save_method
+ bang? ? :save! : :save
+ end
+
private
def initialize_from_match_data(match_data)
@@ -81,4 +93,16 @@ module ActiveRecord
arguments.size == 1 && arguments.first.is_a?(Hash) || super
end
end
+
+ class FindOrCreateByBang < DynamicFinderMatch
+ METHOD_PATTERN = /^find_or_create_by_([_a-zA-Z]\w*)\!$/
+
+ def initialize_from_match_data(match_data)
+ @instantiator = :create
+ end
+
+ def bang?
+ true
+ end
+ end
end
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index 9b2dc096a0..8266427b71 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -84,7 +84,7 @@ module ActiveRecord
relation.table[self.class.primary_key].eq(id).and(
relation.table[lock_col].eq(quote_value(previous_lock_value))
)
- ).arel.compile_update(arel_attributes_values(false, false, attribute_names))
+ ).arel.compile_update(arel_attributes_with_values_for_update(attribute_names))
affected_rows = connection.update stmt
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index c4bce87311..09502bb52c 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -350,7 +350,7 @@ module ActiveRecord
# Updates the associated record with values matching those of the instance attributes.
# Returns the number of affected rows.
def update(attribute_names = @attributes.keys)
- attributes_with_values = arel_attributes_values(false, false, attribute_names)
+ attributes_with_values = arel_attributes_with_values_for_update(attribute_names)
return 0 if attributes_with_values.empty?
klass = self.class
stmt = klass.unscoped.where(klass.arel_table[klass.primary_key].eq(id)).arel.compile_update(attributes_with_values)
@@ -360,7 +360,7 @@ module ActiveRecord
# Creates a record with values matching those of the instance attributes
# and returns its id.
def create
- attributes_values = arel_attributes_values(!id.nil?)
+ attributes_values = arel_attributes_with_values_for_create(!id.nil?)
new_id = self.class.unscoped.insert attributes_values
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 4cd703e0a5..adfacf37ee 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -290,7 +290,7 @@ module ActiveRecord
r.assign_attributes(unprotected_attributes_for_create, :without_protection => true)
end
yield(record) if block_given?
- record.save if match.instantiator == :create
+ record.send(match.save_method) if match.save_record?
end
record
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 87dd513880..d737b34115 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -329,7 +329,7 @@ module ActiveRecord
arel.having(*@having_values.uniq.reject{|h| h.blank?}) unless @having_values.empty?
arel.take(connection.sanitize_limit(@limit_value)) if @limit_value
- arel.skip(@offset_value) if @offset_value
+ arel.skip(@offset_value.to_i) if @offset_value
arel.group(*@group_values.uniq.reject{|g| g.blank?}) unless @group_values.empty?
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 02a7f6af78..6a4f972356 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -378,6 +378,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 1, Firm.find(:first, :order => "id").clients_using_sql.size
end
+ def test_finding_using_sql_take_into_account_only_uniq_ids
+ firm = Firm.find(:first, :order => "id")
+ client = firm.clients_using_sql.first
+ assert_equal client, firm.clients_using_sql.find(client.id, client.id)
+ assert_equal client, firm.clients_using_sql.find(client.id, client.id.to_s)
+ end
+
def test_counting_using_sql
assert_equal 1, Firm.find(:first, :order => "id").clients_using_counter_sql.size
assert Firm.find(:first, :order => "id").clients_using_counter_sql.any?
diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb
index 2c69bfde5b..da93500ce3 100644
--- a/activerecord/test/cases/connection_pool_test.rb
+++ b/activerecord/test/cases/connection_pool_test.rb
@@ -3,6 +3,8 @@ require "cases/helper"
module ActiveRecord
module ConnectionAdapters
class ConnectionPoolTest < ActiveRecord::TestCase
+ attr_reader :pool
+
def setup
super
@@ -25,6 +27,67 @@ module ActiveRecord
@pool.disconnect!
end
+ def active_connections(pool)
+ pool.connections.find_all(&:in_use?)
+ end
+
+ def test_checkout_after_close
+ connection = pool.connection
+ assert connection.in_use?
+
+ connection.close
+ assert !connection.in_use?
+
+ assert pool.connection.in_use?
+ end
+
+ def test_released_connection_moves_between_threads
+ thread_conn = nil
+
+ Thread.new {
+ pool.with_connection do |conn|
+ thread_conn = conn
+ end
+ }.join
+
+ assert thread_conn
+
+ Thread.new {
+ pool.with_connection do |conn|
+ assert_equal thread_conn, conn
+ end
+ }.join
+ end
+
+ def test_with_connection
+ assert_equal 0, active_connections(pool).size
+
+ main_thread = pool.connection
+ assert_equal 1, active_connections(pool).size
+
+ Thread.new {
+ pool.with_connection do |conn|
+ assert conn
+ assert_equal 2, active_connections(pool).size
+ end
+ assert_equal 1, active_connections(pool).size
+ }.join
+
+ main_thread.close
+ assert_equal 0, active_connections(pool).size
+ end
+
+ def test_active_connection_in_use
+ assert !pool.active_connection?
+ main_thread = pool.connection
+
+ assert pool.active_connection?
+
+ main_thread.close
+
+ assert !pool.active_connection?
+ end
+
def test_full_pool_exception
assert_raises(PoolFullError) do
(@pool.size + 1).times do
diff --git a/activerecord/test/cases/dynamic_finder_match_test.rb b/activerecord/test/cases/dynamic_finder_match_test.rb
index e576870317..db619faa83 100644
--- a/activerecord/test/cases/dynamic_finder_match_test.rb
+++ b/activerecord/test/cases/dynamic_finder_match_test.rb
@@ -83,6 +83,14 @@ module ActiveRecord
assert_equal :create, m.instantiator
end
+ def test_find_or_create!
+ m = DynamicFinderMatch.match(:find_or_create_by_foo!)
+ assert_equal :first, m.finder
+ assert m.bang?, 'should be banging'
+ assert_equal %w{ foo }, m.attribute_names
+ assert_equal :create, m.instantiator
+ end
+
def test_find_or_initialize
m = DynamicFinderMatch.match(:find_or_initialize_by_foo)
assert_equal :first, m.finder
diff --git a/activerecord/test/cases/finder_respond_to_test.rb b/activerecord/test/cases/finder_respond_to_test.rb
index 235805a67c..810c1500cc 100644
--- a/activerecord/test/cases/finder_respond_to_test.rb
+++ b/activerecord/test/cases/finder_respond_to_test.rb
@@ -56,6 +56,16 @@ class FinderRespondToTest < ActiveRecord::TestCase
assert_respond_to Topic, :find_or_create_by_title_and_author_name
end
+ def test_should_respond_to_find_or_create_from_one_attribute_bang
+ ensure_topic_method_is_not_cached(:find_or_create_by_title!)
+ assert_respond_to Topic, :find_or_create_by_title!
+ end
+
+ def test_should_respond_to_find_or_create_from_two_attributes_bang
+ ensure_topic_method_is_not_cached(:find_or_create_by_title_and_author_name!)
+ assert_respond_to Topic, :find_or_create_by_title_and_author_name!
+ end
+
def test_should_not_respond_to_find_by_one_missing_attribute
assert !Topic.respond_to?(:find_by_undertitle)
end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 76c041397a..96c8eb6417 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -862,6 +862,28 @@ class FinderTest < ActiveRecord::TestCase
assert another.persisted?
end
+ def test_find_or_create_from_one_attribute_bang
+ number_of_companies = Company.count
+ assert_raises(ActiveRecord::RecordInvalid) { Company.find_or_create_by_name!("") }
+ assert_equal number_of_companies, Company.count
+ sig38 = Company.find_or_create_by_name!("38signals")
+ assert_equal number_of_companies + 1, Company.count
+ assert_equal sig38, Company.find_or_create_by_name!("38signals")
+ assert sig38.persisted?
+ end
+
+ def test_find_or_create_from_two_attributes_bang
+ number_of_companies = Company.count
+ assert_raises(ActiveRecord::RecordInvalid) { Company.find_or_create_by_name_and_firm_id!("", 17) }
+ assert_equal number_of_companies, Company.count
+ sig38 = Company.find_or_create_by_name_and_firm_id!("38signals", 17)
+ assert_equal number_of_companies + 1, Company.count
+ assert_equal sig38, Company.find_or_create_by_name_and_firm_id!("38signals", 17)
+ assert sig38.persisted?
+ assert_equal "38signals", sig38.name
+ assert_equal 17, sig38.firm_id
+ end
+
def test_find_or_create_from_two_attributes_with_one_being_an_aggregate
number_of_customers = Customer.count
created_customer = Customer.find_or_create_by_balance_and_name(Money.new(123), "Elizabeth")
@@ -1185,6 +1207,10 @@ class FinderTest < ActiveRecord::TestCase
end
end
+ def test_finder_with_offset_string
+ assert_nothing_raised(ActiveRecord::StatementInvalid) { Topic.find(:all, :offset => "3") }
+ end
+
protected
def bind(statement, *vars)
if vars.first.is_a?(Hash)
diff --git a/activerecord/test/cases/multiple_db_test.rb b/activerecord/test/cases/multiple_db_test.rb
index 917a03bb34..06d6596725 100644
--- a/activerecord/test/cases/multiple_db_test.rb
+++ b/activerecord/test/cases/multiple_db_test.rb
@@ -86,7 +86,13 @@ class MultipleDbTest < ActiveRecord::TestCase
end
def test_arel_table_engines
- assert_equal Entrant.arel_engine, Bird.arel_engine
+ assert_not_equal Entrant.arel_engine, Bird.arel_engine
+ assert_not_equal Entrant.arel_engine, Course.arel_engine
+ end
+
+ def test_connection
+ assert_equal Entrant.arel_engine.connection, Bird.arel_engine.connection
+ assert_not_equal Entrant.arel_engine.connection, Course.arel_engine.connection
end
unless in_memory_db?
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index 7b1d65c6db..acec230c72 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -462,6 +462,18 @@ class RelationTest < ActiveRecord::TestCase
assert_equal authors(:david), authors.find_or_create_by_name(:name => 'David')
end
+ def test_dynamic_find_or_create_by_attributes_bang
+ authors = Author.scoped
+
+ assert_raises(ActiveRecord::RecordInvalid) { authors.find_or_create_by_name!('') }
+
+ lifo = authors.find_or_create_by_name!('Lifo')
+ assert_equal "Lifo", lifo.name
+ assert lifo.persisted?
+
+ assert_equal authors(:david), authors.find_or_create_by_name!(:name => 'David')
+ end
+
def test_find_id
authors = Author.scoped
diff --git a/activeresource/CHANGELOG.md b/activeresource/CHANGELOG.md
index f305c3fd4a..670cb19f57 100644
--- a/activeresource/CHANGELOG.md
+++ b/activeresource/CHANGELOG.md
@@ -3,6 +3,11 @@
* Adds support for PATCH requests. *dlee*
+## Rails 3.2.2 (March 1, 2012) ##
+
+* No changes.
+
+
## Rails 3.2.1 (January 26, 2012) ##
* Documentation fixes.
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 09ec4ed618..8165b89cde 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -27,6 +27,11 @@
* Unicode database updated to 6.1.0.
+## Rails 3.2.2 (March 1, 2012) ##
+
+* No changes.
+
+
## Rails 3.2.1 (January 26, 2012) ##
* Documentation fixes and improvements.
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index d7408eff9f..b9f196d7a9 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -91,6 +91,7 @@ module ActiveSupport
case
when key.respond_to?(:cache_key) then key.cache_key
when key.is_a?(Array) then key.map { |element| retrieve_cache_key(element) }.to_param
+ when key.respond_to?(:to_a) then retrieve_cache_key(key.to_a)
else key.to_param
end.to_s
end
diff --git a/activesupport/lib/active_support/dependencies/autoload.rb b/activesupport/lib/active_support/dependencies/autoload.rb
index 4c771da096..a1626ebeba 100644
--- a/activesupport/lib/active_support/dependencies/autoload.rb
+++ b/activesupport/lib/active_support/dependencies/autoload.rb
@@ -9,13 +9,16 @@ module ActiveSupport
@@eager_autoload = false
def autoload(const_name, path = @@at_path)
- full = [self.name, @@under_path, const_name.to_s, path].compact.join("::")
- location = path || Inflector.underscore(full)
+ unless path
+ full = [name, @@under_path, const_name.to_s, path].compact.join("::")
+ path = Inflector.underscore(full)
+ end
if @@eager_autoload
- @@autoloads[const_name] = location
+ @@autoloads[const_name] = path
end
- super const_name, location
+
+ super const_name, path
end
def autoload_under(path)
diff --git a/activesupport/lib/active_support/tagged_logging.rb b/activesupport/lib/active_support/tagged_logging.rb
index f6ad861353..88fd438448 100644
--- a/activesupport/lib/active_support/tagged_logging.rb
+++ b/activesupport/lib/active_support/tagged_logging.rb
@@ -13,7 +13,7 @@ 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.
module TaggedLogging
- class Formatter < ActiveSupport::Logger::SimpleFormatter # :nodoc:
+ module Formatter # :nodoc:
# This method is invoked when a log event occurs
def call(severity, timestamp, progname, msg)
super(severity, timestamp, progname, "#{tags_text}#{msg}")
@@ -37,7 +37,7 @@ module ActiveSupport
end
def self.new(logger)
- logger.formatter = Formatter.new
+ logger.formatter.extend Formatter
logger.extend(self)
end
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index b03865da93..ba027f1ff0 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -69,6 +69,10 @@ class CacheKeyTest < ActiveSupport::TestCase
def test_expand_cache_key_of_true
assert_equal 'true', ActiveSupport::Cache.expand_cache_key(true)
end
+
+ def test_expand_cache_key_of_array_like_object
+ assert_equal 'foo/bar/baz', ActiveSupport::Cache.expand_cache_key(%w{foo bar baz}.to_enum)
+ end
end
class CacheStoreSettingTest < ActiveSupport::TestCase
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index d71e3f968f..4544edf0dd 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -490,7 +490,7 @@ class HashExtTest < ActiveSupport::TestCase
original = {:a => 1, :b => 2, :c => 3, :d => 4}
expected = {:a => 1, :b => 2}
- assert_equal expected, {:a => 1, :b => 2, :c => 3, :d => 4}.extract!(:a, :b)
+ assert_equal expected, original.extract!(:a, :b)
end
def test_except
diff --git a/rails.gemspec b/rails.gemspec
index cd7c5d1ee9..b55d0e6859 100644
--- a/rails.gemspec
+++ b/rails.gemspec
@@ -23,5 +23,5 @@ Gem::Specification.new do |s|
s.add_dependency('activeresource', version)
s.add_dependency('actionmailer', version)
s.add_dependency('railties', version)
- s.add_dependency('bundler', '~> 1.0')
+ s.add_dependency('bundler', '~> 1.1')
end
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 960b1ed8ca..e7994e45c6 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -20,6 +20,11 @@
* Rails::Plugin has gone. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies. *Santiago Pastorino*
+## Rails 3.2.2 (March 1, 2012) ##
+
+* No changes.
+
+
## Rails 3.2.1 (January 26, 2012) ##
* Documentation fixes.
diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile
index f007629207..42120e9bad 100644
--- a/railties/guides/source/action_view_overview.textile
+++ b/railties/guides/source/action_view_overview.textile
@@ -431,11 +431,11 @@ form("post")
<form action='/posts/create' method='post'>
<p>
<label for="post_title">Title</label><br />
- <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />
+ <input id="post_title" name="post[title]" type="text" value="Hello World" />
</p>
<p>
<label for="post_body">Body</label><br />
- <textarea cols="40" id="post_body" name="post[body]" rows="20"></textarea>
+ <textarea id="post_body" name="post[body]"></textarea>
</p>
<input name="commit" type="submit" value="Create" />
</form>
@@ -451,7 +451,7 @@ For example, if +@post+ has an attribute +title+ mapped to a +String+ column tha
<ruby>
input("post", "title") # =>
- <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />
+ <input id="post_title" name="post[title]" type="text" value="Hello World" />
</ruby>
h4. RecordTagHelper
@@ -987,8 +987,8 @@ The HTML generated for this would be:
<html>
<form action="/persons/create" method="post">
- <input id="person_first_name" name="person[first_name]" size="30" type="text" />
- <input id="person_last_name" name="person[last_name]" size="30" type="text" />
+ <input id="person_first_name" name="person[first_name]" type="text" />
+ <input id="person_last_name" name="person[last_name]" type="text" />
<input name="commit" type="submit" value="Create" />
</form>
</html>
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile
index d9a62f7574..8e23a577e2 100644
--- a/railties/guides/source/active_record_querying.textile
+++ b/railties/guides/source/active_record_querying.textile
@@ -1133,6 +1133,8 @@ Client.where(:first_name => 'Andy').first_or_create!(:locked => false)
# => ActiveRecord::RecordInvalid: Validation failed: Orders count can't be blank
</ruby>
+As with +first_or_create+ there is a +find_or_create_by!+ method but the +first_or_create!+ method is preferred for clarity.
+
h4. +first_or_initialize+
The +first_or_initialize+ method will work just like +first_or_create+ but it will not call +create+ but +new+. This means that a new model instance will be created in memory but won't be saved to the database. Continuing with the +first_or_create+ example, we now want the client named 'Nick':
diff --git a/railties/guides/source/api_app.textile b/railties/guides/source/api_app.textile
index f2d00c5768..9bbf7b36b1 100644
--- a/railties/guides/source/api_app.textile
+++ b/railties/guides/source/api_app.textile
@@ -13,15 +13,14 @@ endprologue.
h3. What is an API app?
-Traditionally, when people said that they used Rails as an "API", they meant
-providing a programmatically accessible API alongside their web application.
+Traditionally, when people said that they used Rails as an "API", they meant providing a programmatically accessible API alongside their web application.
For example, GitHub provides "an API":http://developer.github.com that you can use from your own custom clients.
With the advent of client-side frameworks, more developers are using Rails to build a backend that is shared between their web application and other native applications.
For example, Twitter uses its "public API":https://dev.twitter.com in its web application, which is built as a static site that consumes JSON resources.
-Instead of using Rails to generate dynamic HTML that will communicate with the server through forms and links, many developers are treating their web application as just another client, delivered as static HTML, CSS and JavaScript, and consuming a simple JSON API
+Instead of using Rails to generate dynamic HTML that will communicate with the server through forms and links, many developers are treating their web application as just another client, delivered as static HTML, CSS and JavaScript, and consuming a simple JSON API
This guide covers building a Rails application that serves JSON resources to an API client *or* client-side framework.
@@ -72,13 +71,13 @@ If you're building a Rails application that will be an API server first and fore
You can generate a new bare Rails app:
<shell>
-$ rails new my_api --api
+$ rails new my_api --http
</shell>
This will do three main things for you:
* Configure your application to start with a more limited set of middleware than normal. Specifically, it will not include any middleware primarily useful for browser applications (like cookie support) by default.
-* Make +ApplicationController+ inherit from +ActionController::API+ instead of +ActionController::Base+. As with middleware, this will leave out any +ActionController+ modules that provide functionality primarily used by browser applications.
+* Make +ApplicationController+ inherit from +ActionController::HTTP+ instead of +ActionController::Base+. As with middleware, this will leave out any +ActionController+ modules that provide functionality primarily used by browser applications.
* Configure the generators to skip generating views, helpers and assets when you generate a new resource.
If you want to take an existing app and make it an API app, follow the following steps.
@@ -86,8 +85,8 @@ If you want to take an existing app and make it an API app, follow the following
In +config/application.rb+ add the following lines at the top of the +Application+ class:
<ruby>
-config.middleware.api_only!
-config.generators.api_only!
+config.middleware.http_only!
+config.generators.http_only!
</ruby>
Change +app/controllers/application_controller.rb+:
@@ -98,7 +97,7 @@ class ApplicationController < ActionController::Base
end
# do
-class ApplicationController < ActionController::API
+class ApplicationController < ActionController::HTTP
end
</ruby>
@@ -240,7 +239,7 @@ Keep in mind that removing these features may remove support for certain feature
h3. Choosing Controller Modules
-An API application (using +ActionController::API+) comes with the following controller modules by default:
+An API application (using +ActionController::HTTP+) comes with the following controller modules by default:
* +AbstractController::Translation+: Support for the +l+ and +t+ localization and translation methods. These delegate to +I18n.translate+ and +I18n.localize+.
* +ActionController::UrlFor+: Makes +url_for+ and friends available.
@@ -253,11 +252,11 @@ An API application (using +ActionController::API+) comes with the following cont
* +AbstractController::Callbacks+: Support for +before_filter+ and friends
* +ActionController::Instrumentation+: Support for the instrumentation hooks defined by +ActionController+ (see "the source":https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/instrumentation.rb for more).
-Other plugins may add additional modules. You can get a list of all modules included into +ActionController::API+ in the rails console:
+Other plugins may add additional modules. You can get a list of all modules included into +ActionController::HTTP+ in the rails console:
<shell>
$ irb
->> ActionController::API.ancestors - ActionController::Metal.ancestors
+>> ActionController::HTTP.ancestors - ActionController::Metal.ancestors
</shell>
h4. Adding Other Modules
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index 7a93a30702..d6e500fc4b 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -248,6 +248,14 @@ They can also be removed from the stack completely:
config.middleware.delete ActionDispatch::BestStandardsSupport
</ruby>
+In addition to these methods to handle the stack, if your application is going to be used as an API endpoint only, the middleware stack can be configured like this:
+
+<ruby>
+config.middleware.http_only!
+</ruby>
+
+By doing this, Rails will create a smaller middleware stack, by not adding some middlewares that are usually useful for browser access only, such as Cookies, Session and Flash, BestStandardsSupport, and MethodOverride. You can always add any of them later manually if you want. Refer to the "API App docs":api_app.html for more info on how to setup your application for API only apps.
+
h4. Configuring i18n
* +config.i18n.default_locale+ sets the default locale of an application used for i18n. Defaults to +:en+.
diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile
index dd993cc3b9..df8b16eb9e 100644
--- a/railties/guides/source/contributing_to_ruby_on_rails.textile
+++ b/railties/guides/source/contributing_to_ruby_on_rails.textile
@@ -309,7 +309,7 @@ Rails follows a simple set of coding style conventions.
* Two spaces, no tabs.
* No trailing whitespace. Blank lines should not have any space.
-* Outdent private/protected from method definitions. Same indentation as the class/module.
+* Indent after private/protected.
* Prefer +&amp;&amp;+/+||+ over +and+/+or+.
* Prefer class << self block over self.method for class methods.
* +MyClass.my_method(my_arg)+ not +my_method( my_arg )+ or +my_method my_arg+.
diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile
index 9f91d12a54..8934667c5e 100644
--- a/railties/guides/source/form_helpers.textile
+++ b/railties/guides/source/form_helpers.textile
@@ -169,11 +169,11 @@ Output:
<textarea id="message" name="message" cols="24" rows="6">Hi, nice site</textarea>
<input id="password" name="password" type="password" />
<input id="parent_id" name="parent_id" type="hidden" value="5" />
-<input id="user_name" name="user[name]" size="30" type="search" />
-<input id="user_phone" name="user[phone]" size="30" type="tel" />
+<input id="user_name" name="user[name]" type="search" />
+<input id="user_phone" name="user[phone]" type="tel" />
<input id="user_born_on" name="user[born_on]" type="date" />
-<input id="user_homepage" size="30" name="user[homepage]" type="url" />
-<input id="user_address" size="30" name="user[address]" type="email" />
+<input id="user_homepage" name="user[homepage]" type="url" />
+<input id="user_address" name="user[address]" type="email" />
</html>
Hidden inputs are not shown to the user but instead hold data like any textual input. Values inside them can be changed with JavaScript.
@@ -239,7 +239,7 @@ The resulting HTML is:
<html>
<form accept-charset="UTF-8" action="/articles/create" method="post" class="nifty_form">
- <input id="article_title" name="article[title]" size="30" type="text" />
+ <input id="article_title" name="article[title]" type="text" />
<textarea id="article_body" name="article[body]" cols="60" rows="12"></textarea>
<input name="commit" type="submit" value="Create" />
</form>
@@ -264,8 +264,8 @@ which produces the following output:
<html>
<form accept-charset="UTF-8" action="/people/create" class="new_person" id="new_person" method="post">
- <input id="person_name" name="person[name]" size="30" type="text" />
- <input id="contact_detail_phone_number" name="contact_detail[phone_number]" size="30" type="text" />
+ <input id="person_name" name="person[name]" type="text" />
+ <input id="contact_detail_phone_number" name="contact_detail[phone_number]" type="text" />
</form>
</html>
@@ -714,9 +714,9 @@ Assuming the person had two addresses, with ids 23 and 45 this would create outp
<html>
<form accept-charset="UTF-8" action="/people/1" class="edit_person" id="edit_person_1" method="post">
- <input id="person_name" name="person[name]" size="30" type="text" />
- <input id="person_address_23_city" name="person[address][23][city]" size="30" type="text" />
- <input id="person_address_45_city" name="person[address][45][city]" size="30" type="text" />
+ <input id="person_name" name="person[name]" type="text" />
+ <input id="person_address_23_city" name="person[address][23][city]" type="text" />
+ <input id="person_address_45_city" name="person[address][45][city]" type="text" />
</form>
</html>
@@ -739,7 +739,7 @@ To create more intricate nestings, you can specify the first part of the input n
will create inputs like
<html>
-<input id="person_address_primary_1_city" name="person[address][primary][1][city]" size="30" type="text" value="bologna" />
+<input id="person_address_primary_1_city" name="person[address][primary][1][city]" type="text" value="bologna" />
</html>
As a general rule the final input name is the concatenation of the name given to +fields_for+/+form_for+, the index value and the name of the attribute. You can also pass an +:index+ option directly to helpers such as +text_field+, but it is usually less repetitive to specify this at the form builder level rather than on individual input controls.
diff --git a/railties/guides/source/nested_model_forms.textile b/railties/guides/source/nested_model_forms.textile
index 4b1fd2e0ac..82c9ab9d36 100644
--- a/railties/guides/source/nested_model_forms.textile
+++ b/railties/guides/source/nested_model_forms.textile
@@ -131,7 +131,7 @@ This will generate the following html:
<html>
<form action="/people" class="new_person" id="new_person" method="post">
- <input id="person_name" name="person[name]" size="30" type="text" />
+ <input id="person_name" name="person[name]" type="text" />
</form>
</html>
@@ -153,9 +153,9 @@ This generates:
<html>
<form action="/people" class="new_person" id="new_person" method="post">
- <input id="person_name" name="person[name]" size="30" type="text" />
+ <input id="person_name" name="person[name]" type="text" />
- <input id="person_address_attributes_street" name="person[address_attributes][street]" size="30" type="text" />
+ <input id="person_address_attributes_street" name="person[address_attributes][street]" type="text" />
</form>
</html>
@@ -194,10 +194,10 @@ Which generates:
<html>
<form action="/people" class="new_person" id="new_person" method="post">
- <input id="person_name" name="person[name]" size="30" type="text" />
+ <input id="person_name" name="person[name]" type="text" />
- <input id="person_projects_attributes_0_name" name="person[projects_attributes][0][name]" size="30" type="text" />
- <input id="person_projects_attributes_1_name" name="person[projects_attributes][1][name]" size="30" type="text" />
+ <input id="person_projects_attributes_0_name" name="person[projects_attributes][0][name]" type="text" />
+ <input id="person_projects_attributes_1_name" name="person[projects_attributes][1][name]" type="text" />
</form>
</html>
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 10fa63c303..3191fe68a7 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -239,7 +239,7 @@ module Rails
middleware.use ::Rack::Lock unless config.allow_concurrency
middleware.use ::Rack::Runtime
- middleware.use ::Rack::MethodOverride unless config.middleware.api_only?
+ middleware.use ::Rack::MethodOverride unless config.middleware.http_only?
middleware.use ::ActionDispatch::RequestId
middleware.use ::Rails::Rack::Logger, config.log_tags # must come after Rack::MethodOverride to properly log overridden methods
middleware.use ::ActionDispatch::ShowExceptions, config.exceptions_app || ActionDispatch::PublicExceptions.new(Rails.public_path)
@@ -252,9 +252,9 @@ module Rails
end
middleware.use ::ActionDispatch::Callbacks
- middleware.use ::ActionDispatch::Cookies unless config.middleware.api_only?
+ middleware.use ::ActionDispatch::Cookies unless config.middleware.http_only?
- if !config.middleware.api_only? && config.session_store
+ if !config.middleware.http_only? && config.session_store
if config.force_ssl && !config.session_options.key?(:secure)
config.session_options[:secure] = true
end
@@ -267,7 +267,7 @@ module Rails
middleware.use ::Rack::ConditionalGet
middleware.use ::Rack::ETag, "no-cache"
- if !config.middleware.api_only? && config.action_dispatch.best_standards_support
+ if !config.middleware.http_only? && config.action_dispatch.best_standards_support
middleware.use ::ActionDispatch::BestStandardsSupport, config.action_dispatch.best_standards_support
end
end
diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb
index 93a0fba10b..e567df7162 100644
--- a/railties/lib/rails/application/bootstrap.rb
+++ b/railties/lib/rails/application/bootstrap.rb
@@ -32,9 +32,9 @@ module Rails
f.binmode
f.sync = config.autoflush_log # if true make sure every write flushes
- logger = ActiveSupport::TaggedLogging.new(
- ActiveSupport::Logger.new(f)
- )
+ logger = ActiveSupport::Logger.new f
+ logger.formatter = config.log_formatter
+ logger = ActiveSupport::TaggedLogging.new(logger)
logger.level = ActiveSupport::Logger.const_get(config.log_level.to_s.upcase)
logger
rescue StandardError
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 0f5fc2b7bc..1cfcd30c5b 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -8,7 +8,7 @@ module Rails
attr_accessor :allow_concurrency, :asset_host, :asset_path, :assets, :autoflush_log,
:cache_classes, :cache_store, :consider_all_requests_local, :console,
:dependency_loading, :exceptions_app, :file_watcher, :filter_parameters,
- :force_ssl, :helpers_paths, :logger, :log_tags, :preload_frameworks,
+ :force_ssl, :helpers_paths, :logger, :log_formatter, :log_tags, :preload_frameworks,
:railties_order, :relative_url_root, :secret_token,
:serve_static_assets, :ssl_options, :static_cache_control, :session_options,
:time_zone, :reload_classes_only_on_change, :use_schema_cache_dump
@@ -41,6 +41,7 @@ module Rails
@file_watcher = ActiveSupport::FileUpdateChecker
@exceptions_app = nil
@autoflush_log = true
+ @log_formatter = ActiveSupport::Logger::SimpleFormatter.new
@use_schema_cache_dump = true
@assets = ActiveSupport::OrderedOptions.new
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 0b757cbe28..a608693ca4 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -71,6 +71,8 @@ module Rails
wrapped_app # touch the app so the logger is set up
console = ActiveSupport::Logger.new($stdout)
+ console.formatter = Rails.logger.formatter
+
Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
end
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index 0efa21d82c..d8185bcb34 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -6,17 +6,54 @@ require 'rails/rack'
module Rails
module Configuration
- class MiddlewareStackProxy #:nodoc:
+ # MiddlewareStackProxy is a proxy for the Rails middleware stack that allows
+ # you to configure middlewares in your application. It works basically as a
+ # command recorder, saving each command to be applied after initialization
+ # over the default middleware stack, so you can add, swap, or remove any
+ # middleware in Rails.
+ #
+ # You can add your own middlewares by using the +config.middleware.use+ method:
+ #
+ # config.middleware.use Magical::Unicorns
+ #
+ # This will put the +Magical::Unicorns+ middleware on the end of the stack.
+ # You can use +insert_before+ if you wish to add a middleware before another:
+ #
+ # config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns
+ #
+ # There's also +insert_after+ which will insert a middleware after another:
+ #
+ # config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns
+ #
+ # Middlewares can also be completely swapped out and replaced with others:
+ #
+ # config.middleware.swap ActionDispatch::BestStandardsSupport, Magical::Unicorns
+ #
+ # And finally they can also be removed from the stack completely:
+ #
+ # config.middleware.delete ActionDispatch::BestStandardsSupport
+ #
+ # In addition to these methods to handle the stack, if your application is
+ # going to be used as an API endpoint only, the middleware stack can be
+ # configured like this:
+ #
+ # config.middleware.http_only!
+ #
+ # By doing this, Rails will create a smaller middleware stack, by not adding
+ # some middlewares that are usually useful for browser access only, such as
+ # Cookies, Session and Flash, BestStandardsSupport, and MethodOverride. You
+ # can always add any of them later manually if you want.
+ class MiddlewareStackProxy
def initialize
@operations = []
- @api_only = false
+ @http_only = false
end
- attr_reader :api_only
- alias :api_only? :api_only
+ attr_reader :http_only
+ alias :http_only? :http_only
- def api_only!
- @api_only = true
+ def http_only!
+ @http_only = true
end
def insert_before(*args, &block)
@@ -41,7 +78,7 @@ module Rails
@operations << [:delete, args, block]
end
- def merge_into(other)
+ def merge_into(other) #:nodoc:
@operations.each do |operation, args, block|
other.send(operation, *args, &block)
end
diff --git a/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb b/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb
index e8065d9505..b3d6adad2a 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb
@@ -1,3 +1,5 @@
class ApplicationController < ActionController::Base
- protect_from_forgery
+ # prevent CSRF attacks by raising an exception,
+ # if your application has an API, you'll probably need to use :reset_session
+ protect_from_forgery :with => :exception
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index 7041550fd0..d0d9083c37 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
@@ -73,4 +73,7 @@
# Disable automatic flushing of the log to improve performance.
# config.autoflush_log = false
+
+ # Use default logging formatter so that PID and timestamp are not suppressed
+ config.log_formatter = ::Logger::Formatter.new
end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb
index dcd3b276e3..8d45b2bbd9 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb
@@ -8,3 +8,8 @@ Rails.backtrace_cleaner.remove_silencers!
# Load support files
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
+
+# Load fixtures from the engine
+if ActiveSupport::TestCase.method_defined?(:fixture_path)
+ ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
+end \ No newline at end of file
diff --git a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
index f7e907a017..4c07baae36 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
@@ -8,10 +8,31 @@ module TestUnit
check_class_collision :suffix => "ControllerTest"
+ argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
+
def create_test_files
template 'functional_test.rb',
File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb")
end
+
+ private
+
+ def resource_attributes
+ key_value singular_table_name, "{ #{attributes_hash} }"
+ end
+
+ def attributes_hash
+ return if accessible_attributes.empty?
+
+ accessible_attributes.map do |a|
+ name = a.name
+ "#{name}: @#{singular_table_name}.#{name}"
+ end.sort.join(', ')
+ end
+
+ def accessible_attributes
+ attributes.reject(&:reference?)
+ end
end
end
end
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
index 9ec2e34545..19894443d5 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
@@ -19,7 +19,7 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
test "should create <%= singular_table_name %>" do
assert_difference('<%= class_name %>.count') do
- post :create, <%= key_value singular_table_name, "@#{singular_table_name}.attributes" %>
+ post :create, <%= resource_attributes %>
end
assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
@@ -36,7 +36,7 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
end
test "should update <%= singular_table_name %>" do
- put :update, <%= key_value :id, "@#{singular_table_name}" %>, <%= key_value singular_table_name, "@#{singular_table_name}.attributes" %>
+ put :update, <%= key_value :id, "@#{singular_table_name}" %>, <%= resource_attributes %>
assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
end
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index c9310aff87..ac5ac2b93e 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -275,19 +275,23 @@ module ApplicationTests
require "#{app_path}/config/environment"
+ token = "cf50faa3fe97702ca1ae"
+ PostsController.any_instance.stubs(:form_authenticity_token).returns(token)
+ params = {:authenticity_token => token}
+
get "/posts/1"
assert_match /patch/, last_response.body
- patch "/posts/1"
+ patch "/posts/1", params
assert_match /update/, last_response.body
- patch "/posts/1"
+ patch "/posts/1", params
assert_equal 200, last_response.status
- put "/posts/1"
+ put "/posts/1", params
assert_match /update/, last_response.body
- put "/posts/1"
+ put "/posts/1", params
assert_equal 200, last_response.status
end
@@ -528,6 +532,12 @@ module ApplicationTests
end
RUBY
+ app_file 'app/controllers/application_controller.rb', <<-RUBY
+ class ApplicationController < ActionController::Base
+ protect_from_forgery :with => :reset_session # as we are testing API here
+ end
+ RUBY
+
app_file 'app/controllers/posts_controller.rb', <<-RUBY
class PostsController < ApplicationController
def create
diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb
index a0e88cd0f0..a08e5b2374 100644
--- a/railties/test/application/initializers/frameworks_test.rb
+++ b/railties/test/application/initializers/frameworks_test.rb
@@ -1,4 +1,5 @@
require "isolation/abstract_unit"
+require 'set'
module ApplicationTests
class FrameworksTest < ActiveSupport::TestCase
@@ -66,7 +67,7 @@ module ApplicationTests
require "#{app_path}/config/environment"
assert Foo.method_defined?(:foo_path)
assert Foo.method_defined?(:main_app)
- assert_equal ["notify"], Foo.action_methods
+ assert_equal Set.new(["notify"]), Foo.action_methods
end
test "allows to not load all helpers for controllers" do
@@ -196,9 +197,8 @@ module ApplicationTests
test "use schema cache dump" do
Dir.chdir(app_path) do
- `rails generate model post title:string`
- `bundle exec rake db:migrate`
- `bundle exec rake db:schema:cache:dump`
+ `rails generate model post title:string;
+ bundle exec rake db:migrate db:schema:cache:dump`
end
require "#{app_path}/config/environment"
ActiveRecord::Base.connection.drop_table("posts") # force drop posts table for test.
@@ -207,17 +207,13 @@ module ApplicationTests
test "expire schema cache dump" do
Dir.chdir(app_path) do
- `rails generate model post title:string`
- `bundle exec rake db:migrate`
- `bundle exec rake db:schema:cache:dump`
-
- `bundle exec rake db:rollback`
+ `rails generate model post title:string;
+ bundle exec rake db:migrate db:schema:cache:dump db:rollback`
end
silence_warnings {
require "#{app_path}/config/environment"
assert !ActiveRecord::Base.connection.schema_cache.tables["posts"]
}
end
-
end
end
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index a190a31fc7..712a555c4a 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -53,7 +53,7 @@ module ApplicationTests
end
test "api middleware stack" do
- add_to_config "config.middleware.api_only!"
+ add_to_config "config.middleware.http_only!"
add_to_config "config.force_ssl = true"
add_to_config "config.action_dispatch.x_sendfile_header = 'X-Sendfile'"
@@ -216,7 +216,6 @@ module ApplicationTests
assert_equal etag, last_response.headers["Etag"]
get "/?nothing=true"
- puts last_response.body
assert_equal 200, last_response.status
assert_equal "", last_response.body
assert_equal "text/html; charset=utf-8", last_response.headers["Content-Type"]
diff --git a/railties/test/application/rake/migrations_test.rb b/railties/test/application/rake/migrations_test.rb
index c94334f189..0a47fd014c 100644
--- a/railties/test/application/rake/migrations_test.rb
+++ b/railties/test/application/rake/migrations_test.rb
@@ -16,44 +16,45 @@ module ApplicationTests
test 'running migrations with given scope' do
Dir.chdir(app_path) do
`rails generate model user username:string password:string`
- end
- app_file "db/migrate/01_a_migration.bukkits.rb", <<-MIGRATION
- class AMigration < ActiveRecord::Migration
- end
- MIGRATION
- output = Dir.chdir(app_path) { `rake db:migrate SCOPE=bukkits` }
- assert_no_match(/create_table\(:users\)/, output)
- assert_no_match(/CreateUsers/, output)
- assert_no_match(/add_column\(:users, :email, :string\)/, output)
+ app_file "db/migrate/01_a_migration.bukkits.rb", <<-MIGRATION
+ class AMigration < ActiveRecord::Migration
+ end
+ MIGRATION
+
+ output = `rake db:migrate SCOPE=bukkits`
+ assert_no_match(/create_table\(:users\)/, output)
+ assert_no_match(/CreateUsers/, output)
+ assert_no_match(/add_column\(:users, :email, :string\)/, output)
- assert_match(/AMigration: migrated/, output)
+ assert_match(/AMigration: migrated/, output)
- output = Dir.chdir(app_path) { `rake db:migrate SCOPE=bukkits VERSION=0` }
- assert_no_match(/drop_table\(:users\)/, output)
- assert_no_match(/CreateUsers/, output)
- assert_no_match(/remove_column\(:users, :email\)/, output)
+ output = `rake db:migrate SCOPE=bukkits VERSION=0`
+ assert_no_match(/drop_table\(:users\)/, output)
+ assert_no_match(/CreateUsers/, output)
+ assert_no_match(/remove_column\(:users, :email\)/, output)
- assert_match(/AMigration: reverted/, output)
+ assert_match(/AMigration: reverted/, output)
+ end
end
test 'model and migration generator with change syntax' do
Dir.chdir(app_path) do
- `rails generate model user username:string password:string`
- `rails generate migration add_email_to_users email:string`
+ `rails generate model user username:string password:string;
+ rails generate migration add_email_to_users email:string`
+
+ output = `rake db:migrate`
+ assert_match(/create_table\(:users\)/, output)
+ assert_match(/CreateUsers: migrated/, output)
+ assert_match(/add_column\(:users, :email, :string\)/, output)
+ assert_match(/AddEmailToUsers: migrated/, output)
+
+ output = `rake db:rollback STEP=2`
+ assert_match(/drop_table\("users"\)/, output)
+ assert_match(/CreateUsers: reverted/, output)
+ assert_match(/remove_column\("users", :email\)/, output)
+ assert_match(/AddEmailToUsers: reverted/, output)
end
-
- output = Dir.chdir(app_path){ `rake db:migrate` }
- assert_match(/create_table\(:users\)/, output)
- assert_match(/CreateUsers: migrated/, output)
- assert_match(/add_column\(:users, :email, :string\)/, output)
- assert_match(/AddEmailToUsers: migrated/, output)
-
- output = Dir.chdir(app_path){ `rake db:rollback STEP=2` }
- assert_match(/drop_table\("users"\)/, output)
- assert_match(/CreateUsers: reverted/, output)
- assert_match(/remove_column\("users", :email\)/, output)
- assert_match(/AddEmailToUsers: reverted/, output)
end
test 'migration status when schema migrations table is not present' do
@@ -63,94 +64,94 @@ module ApplicationTests
test 'test migration status' do
Dir.chdir(app_path) do
- `rails generate model user username:string password:string`
- `rails generate migration add_email_to_users email:string`
- end
+ `rails generate model user username:string password:string;
+ rails generate migration add_email_to_users email:string;
+ rake db:migrate`
- Dir.chdir(app_path) { `rake db:migrate` }
- output = Dir.chdir(app_path) { `rake db:migrate:status` }
+ output = `rake db:migrate:status`
- assert_match(/up\s+\d{14}\s+Create users/, output)
- assert_match(/up\s+\d{14}\s+Add email to users/, output)
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/up\s+\d{14}\s+Add email to users/, output)
- Dir.chdir(app_path) { `rake db:rollback STEP=1` }
- output = Dir.chdir(app_path) { `rake db:migrate:status` }
+ `rake db:rollback STEP=1`
+ output = `rake db:migrate:status`
- assert_match(/up\s+\d{14}\s+Create users/, output)
- assert_match(/down\s+\d{14}\s+Add email to users/, output)
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/down\s+\d{14}\s+Add email to users/, output)
+ end
end
test 'migration status without timestamps' do
add_to_config('config.active_record.timestamped_migrations = false')
Dir.chdir(app_path) do
- `rails generate model user username:string password:string`
- `rails generate migration add_email_to_users email:string`
- end
+ `rails generate model user username:string password:string;
+ rails generate migration add_email_to_users email:string;
+ rake db:migrate`
- Dir.chdir(app_path) { `rake db:migrate` }
- output = Dir.chdir(app_path) { `rake db:migrate:status` }
+ output = `rake db:migrate:status`
- assert_match(/up\s+\d{3,}\s+Create users/, output)
- assert_match(/up\s+\d{3,}\s+Add email to users/, output)
+ assert_match(/up\s+\d{3,}\s+Create users/, output)
+ assert_match(/up\s+\d{3,}\s+Add email to users/, output)
- Dir.chdir(app_path) { `rake db:rollback STEP=1` }
- output = Dir.chdir(app_path) { `rake db:migrate:status` }
+ `rake db:rollback STEP=1`
+ output = `rake db:migrate:status`
- assert_match(/up\s+\d{3,}\s+Create users/, output)
- assert_match(/down\s+\d{3,}\s+Add email to users/, output)
+ assert_match(/up\s+\d{3,}\s+Create users/, output)
+ assert_match(/down\s+\d{3,}\s+Add email to users/, output)
+ end
end
test 'test migration status after rollback and redo' do
Dir.chdir(app_path) do
- `rails generate model user username:string password:string`
- `rails generate migration add_email_to_users email:string`
- end
+ `rails generate model user username:string password:string;
+ rails generate migration add_email_to_users email:string;
+ rake db:migrate`
- Dir.chdir(app_path) { `rake db:migrate` }
- output = Dir.chdir(app_path) { `rake db:migrate:status` }
+ output = `rake db:migrate:status`
- assert_match(/up\s+\d{14}\s+Create users/, output)
- assert_match(/up\s+\d{14}\s+Add email to users/, output)
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/up\s+\d{14}\s+Add email to users/, output)
- Dir.chdir(app_path) { `rake db:rollback STEP=2` }
- output = Dir.chdir(app_path) { `rake db:migrate:status` }
+ `rake db:rollback STEP=2`
+ output = `rake db:migrate:status`
- assert_match(/down\s+\d{14}\s+Create users/, output)
- assert_match(/down\s+\d{14}\s+Add email to users/, output)
+ assert_match(/down\s+\d{14}\s+Create users/, output)
+ assert_match(/down\s+\d{14}\s+Add email to users/, output)
- Dir.chdir(app_path) { `rake db:migrate:redo` }
- output = Dir.chdir(app_path) { `rake db:migrate:status` }
+ `rake db:migrate:redo`
+ output = `rake db:migrate:status`
- assert_match(/up\s+\d{14}\s+Create users/, output)
- assert_match(/up\s+\d{14}\s+Add email to users/, output)
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/up\s+\d{14}\s+Add email to users/, output)
+ end
end
test 'migration status after rollback and redo without timestamps' do
add_to_config('config.active_record.timestamped_migrations = false')
Dir.chdir(app_path) do
- `rails generate model user username:string password:string`
- `rails generate migration add_email_to_users email:string`
- end
+ `rails generate model user username:string password:string;
+ rails generate migration add_email_to_users email:string;
+ rake db:migrate`
- Dir.chdir(app_path) { `rake db:migrate` }
- output = Dir.chdir(app_path) { `rake db:migrate:status` }
+ output = `rake db:migrate:status`
- assert_match(/up\s+\d{3,}\s+Create users/, output)
- assert_match(/up\s+\d{3,}\s+Add email to users/, output)
+ assert_match(/up\s+\d{3,}\s+Create users/, output)
+ assert_match(/up\s+\d{3,}\s+Add email to users/, output)
- Dir.chdir(app_path) { `rake db:rollback STEP=2` }
- output = Dir.chdir(app_path) { `rake db:migrate:status` }
+ `rake db:rollback STEP=2`
+ output = `rake db:migrate:status`
- assert_match(/down\s+\d{3,}\s+Create users/, output)
- assert_match(/down\s+\d{3,}\s+Add email to users/, output)
+ assert_match(/down\s+\d{3,}\s+Create users/, output)
+ assert_match(/down\s+\d{3,}\s+Add email to users/, output)
- Dir.chdir(app_path) { `rake db:migrate:redo` }
- output = Dir.chdir(app_path) { `rake db:migrate:status` }
+ `rake db:migrate:redo`
+ output = `rake db:migrate:status`
- assert_match(/up\s+\d{3,}\s+Create users/, output)
- assert_match(/up\s+\d{3,}\s+Add email to users/, output)
+ assert_match(/up\s+\d{3,}\s+Create users/, output)
+ assert_match(/up\s+\d{3,}\s+Add email to users/, output)
+ end
end
end
end
diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb
index 4ab20afc47..b66433f64d 100644
--- a/railties/test/application/rake/notes_test.rb
+++ b/railties/test/application/rake/notes_test.rb
@@ -3,7 +3,7 @@ require "isolation/abstract_unit"
module ApplicationTests
module RakeTests
class RakeNotesTest < ActiveSupport::TestCase
- def setup
+ def setup
build_app
require "rails/all"
end
@@ -13,7 +13,6 @@ module ApplicationTests
end
test 'notes' do
-
app_file "app/views/home/index.html.erb", "<% # TODO: note in erb %>"
app_file "app/views/home/index.html.haml", "-# TODO: note in haml"
app_file "app/views/home/index.html.slim", "/ TODO: note in slim"
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index 9515e40b6e..fed9dce8e1 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -107,9 +107,9 @@ module ApplicationTests
def test_loading_specific_fixtures
Dir.chdir(app_path) do
- `rails generate model user username:string password:string`
- `rails generate model product name:string`
- `rake db:migrate`
+ `rails generate model user username:string password:string;
+ rails generate model product name:string;
+ rake db:migrate`
end
require "#{rails_root}/config/environment"
@@ -124,8 +124,8 @@ module ApplicationTests
def test_scaffold_tests_pass_by_default
content = Dir.chdir(app_path) do
- `rails generate scaffold user username:string password:string`
- `bundle exec rake db:migrate db:test:clone test`
+ `rails generate scaffold user username:string password:string;
+ bundle exec rake db:migrate db:test:clone test`
end
assert_match(/\d+ tests, \d+ assertions, 0 failures, 0 errors/, content)
@@ -133,29 +133,26 @@ module ApplicationTests
def test_rake_dump_structure_should_respect_db_structure_env_variable
Dir.chdir(app_path) do
- `bundle exec rake db:migrate` # ensure we have a schema_migrations table to dump
- `bundle exec rake db:structure:dump DB_STRUCTURE=db/my_structure.sql`
+ # ensure we have a schema_migrations table to dump
+ `bundle exec rake db:migrate db:structure:dump DB_STRUCTURE=db/my_structure.sql`
end
assert File.exists?(File.join(app_path, 'db', 'my_structure.sql'))
end
def test_rake_dump_schema_cache
Dir.chdir(app_path) do
- `rails generate model post title:string`
- `rails generate model product name:string`
- `bundle exec rake db:migrate`
- `bundle exec rake db:schema:cache:dump`
+ `rails generate model post title:string;
+ rails generate model product name:string;
+ bundle exec rake db:migrate db:schema:cache:dump`
end
assert File.exists?(File.join(app_path, 'db', 'schema_cache.dump'))
end
def test_rake_clear_schema_cache
Dir.chdir(app_path) do
- `bundle exec rake db:schema:cache:dump`
- `bundle exec rake db:schema:cache:clear`
+ `bundle exec rake db:schema:cache:dump db:schema:cache:clear`
end
assert !File.exists?(File.join(app_path, 'db', 'schema_cache.dump'))
end
-
end
end
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index 1382133d7b..03a753151d 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -75,6 +75,19 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
assert_file "test/functional/users_controller_test.rb" do |content|
assert_match(/class UsersControllerTest < ActionController::TestCase/, content)
assert_match(/test "should get index"/, content)
+ assert_match(/post :create, user: { age: @user.age, name: @user.name }/, content)
+ assert_match(/put :update, id: @user, user: { age: @user.age, name: @user.name }/, content)
+ end
+ end
+
+ def test_functional_tests_without_attributes
+ run_generator ["User"]
+
+ assert_file "test/functional/users_controller_test.rb" do |content|
+ assert_match(/class UsersControllerTest < ActionController::TestCase/, content)
+ assert_match(/test "should get index"/, content)
+ assert_match(/post :create, user: { }/, content)
+ assert_match(/put :update, id: @user, user: { }/, content)
end
end
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index 2db8090621..f4f0147156 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -62,8 +62,11 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
end
end
- assert_file "test/functional/product_lines_controller_test.rb",
- /class ProductLinesControllerTest < ActionController::TestCase/
+ assert_file "test/functional/product_lines_controller_test.rb" do |test|
+ assert_match(/class ProductLinesControllerTest < ActionController::TestCase/, test)
+ assert_match(/post :create, product_line: { title: @product_line.title }/, test)
+ assert_match(/put :update, id: @product_line, product_line: { title: @product_line.title }/, test)
+ end
# Views
%w(
@@ -85,6 +88,17 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_file "app/assets/stylesheets/product_lines.css"
end
+ def test_functional_tests_without_attributes
+ run_generator ["product_line"]
+
+ assert_file "test/functional/product_lines_controller_test.rb" do |content|
+ assert_match(/class ProductLinesControllerTest < ActionController::TestCase/, content)
+ assert_match(/test "should get index"/, content)
+ assert_match(/post :create, product_line: { }/, content)
+ assert_match(/put :update, id: @product_line, product_line: { }/, content)
+ end
+ end
+
def test_scaffold_on_revoke
run_generator
run_generator ["product_line"], :behavior => :revoke