aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile15
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb26
-rw-r--r--actionpack/lib/action_dispatch/middleware/show_exceptions.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb23
-rw-r--r--actionpack/test/controller/output_escaping_test.rb2
-rw-r--r--actionpack/test/controller/render_test.rb12
-rw-r--r--actionpack/test/controller/request_forgery_protection_test.rb2
-rw-r--r--actionpack/test/controller/test_test.rb2
-rw-r--r--actionpack/test/controller/webservice_test.rb4
-rw-r--r--actionpack/test/dispatch/cookies_test.rb30
-rw-r--r--actionpack/test/template/atom_feed_helper_test.rb2
-rw-r--r--actionpack/test/template/form_options_helper_test.rb66
-rw-r--r--activemodel/lib/active_model/conversion.rb9
-rw-r--r--activemodel/lib/active_model/lint.rb1
-rw-r--r--activemodel/test/cases/mass_assignment_security_test.rb6
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb2
-rw-r--r--activerecord/lib/active_record/session_store.rb15
-rw-r--r--activerecord/test/cases/adapters/mysql/connection_test.rb1
-rw-r--r--activerecord/test/cases/adapters/mysql/sp_test.rb15
-rw-r--r--activerecord/test/cases/aggregations_test.rb2
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb2
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb4
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb2
-rw-r--r--activerecord/test/cases/associations/join_model_test.rb4
-rw-r--r--activerecord/test/cases/method_scoping_test.rb2
-rw-r--r--activerecord/test/cases/migration_test.rb3
-rw-r--r--activerecord/test/cases/named_scope_test.rb4
-rw-r--r--activerecord/test/cases/primary_keys_test.rb4
-rw-r--r--activerecord/test/cases/relation_scoping_test.rb2
-rw-r--r--activerecord/test/cases/relations_test.rb4
-rw-r--r--activerecord/test/cases/timestamp_test.rb16
-rw-r--r--activerecord/test/cases/transaction_callbacks_test.rb4
-rw-r--r--activerecord/test/connections/native_oracle/connection.rb7
-rw-r--r--activerecord/test/schema/mysql_specific_schema.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/array/conversions.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/object.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/object/returning.rb43
-rw-r--r--activesupport/lib/active_support/log_subscriber.rb63
-rw-r--r--activesupport/lib/active_support/testing/assertions.rb10
-rw-r--r--activesupport/test/caching_test.rb4
-rw-r--r--activesupport/test/core_ext/array_ext_test.rb5
-rw-r--r--activesupport/test/core_ext/class/attribute_test.rb5
-rwxr-xr-xci/ci_build.rb8
-rw-r--r--railties/guides/source/getting_started.textile8
-rw-r--r--railties/guides/source/routing.textile24
-rw-r--r--railties/lib/rails/application/configuration.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/routes.rb8
-rw-r--r--railties/lib/rails/tasks/routes.rake32
-rw-r--r--railties/test/application/configuration_test.rb20
51 files changed, 363 insertions, 185 deletions
diff --git a/Gemfile b/Gemfile
index d594d20fac..714437d917 100644
--- a/Gemfile
+++ b/Gemfile
@@ -50,11 +50,14 @@ platforms :jruby do
end
end
-env 'CI' do
- gem "nokogiri", ">= 1.4.3.1"
-
- platforms :ruby_18 do
- # fcgi gem doesn't compile on 1.9
- gem "fcgi", ">= 0.8.8"
+# gems that are necessary for ActiveRecord tests with Oracle database
+if ENV['ORACLE_ENHANCED_PATH'] || ENV['ORACLE_ENHANCED']
+ platforms :ruby do
+ gem 'ruby-oci8', ">= 2.0.4"
+ end
+ if ENV['ORACLE_ENHANCED_PATH']
+ gem 'activerecord-oracle_enhanced-adapter', :path => ENV['ORACLE_ENHANCED_PATH']
+ else
+ gem "activerecord-oracle_enhanced-adapter", :git => "git://github.com/rsim/oracle-enhanced.git"
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 4d33cd3b0c..c281e323e5 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -69,16 +69,26 @@ module ActionDispatch
class CookieJar < Hash #:nodoc:
- # This regular expression is used to split the levels of a domain
- # So www.example.co.uk gives:
- # $1 => www.
- # $2 => example
- # $3 => co.uk
- DOMAIN_REGEXP = /^(.*\.)*(.*)\.(...|...\...|....|..\...|..)$/
+ # This regular expression is used to split the levels of a domain.
+ # The top level domain can be any string without a period or
+ # **.**, ***.** style TLDs like co.uk or com.au
+ #
+ # www.example.co.uk gives:
+ # $1 => example
+ # $2 => co.uk
+ #
+ # example.com gives:
+ # $1 => example
+ # $2 => com
+ #
+ # lots.of.subdomains.example.local gives:
+ # $1 => example
+ # $2 => local
+ DOMAIN_REGEXP = /([^.]*)\.([^.]*|..\...|...\...)$/
def self.build(request)
secret = request.env[TOKEN_KEY]
- host = request.env["HTTP_HOST"]
+ host = request.host
new(secret, host).tap do |hash|
hash.update(request.cookies)
@@ -104,7 +114,7 @@ module ActionDispatch
if options[:domain] == :all
@host =~ DOMAIN_REGEXP
- options[:domain] = ".#{$2}.#{$3}"
+ options[:domain] = ".#{$1}.#{$2}"
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
index a7d3cb473f..ef0c9c51f5 100644
--- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
@@ -127,7 +127,7 @@ module ActionDispatch
ActiveSupport::Deprecation.silence do
message = "\n#{exception.class} (#{exception.message}):\n"
- message << exception.annoted_source_code if exception.respond_to?(:annoted_source_code)
+ message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
message << " " << application_trace(exception).join("\n ")
logger.fatal("#{message}\n\n")
end
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index 698cd3e4cd..43cbba8a0a 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -298,17 +298,18 @@ module ActionView
return container if String === container
container = container.to_a if Hash === container
- selected, disabled = extract_selected_and_disabled(selected)
+ selected, disabled = extract_selected_and_disabled(selected).map do | r |
+ Array.wrap(r).map(&:to_s)
+ end
- options_for_select = container.map do |element|
+ container.map do |element|
html_attributes = option_html_attributes(element)
- text, value = option_text_and_value(element)
+ text, value = option_text_and_value(element).map(&:to_s)
selected_attribute = ' selected="selected"' if option_value_selected?(value, selected)
disabled_attribute = ' disabled="disabled"' if disabled && option_value_selected?(value, disabled)
- %(<option value="#{html_escape(value.to_s)}"#{selected_attribute}#{disabled_attribute}#{html_attributes}>#{html_escape(text.to_s)}</option>)
- end
+ %(<option value="#{html_escape(value)}"#{selected_attribute}#{disabled_attribute}#{html_attributes}>#{html_escape(text)}</option>)
+ end.join("\n").html_safe
- options_for_select.join("\n").html_safe
end
# Returns a string of option tags that have been compiled by iterating over the +collection+ and assigning the
@@ -493,7 +494,7 @@ module ActionView
end
zone_options += options_for_select(convert_zones[zones], selected)
- zone_options
+ zone_options.html_safe
end
private
@@ -528,10 +529,12 @@ module ActionView
end
def extract_selected_and_disabled(selected)
- if selected.is_a?(Hash)
- [selected[:selected], selected[:disabled]]
+ if selected.is_a?(Proc)
+ [ selected, nil ]
else
- [selected, nil]
+ selected = Array.wrap(selected)
+ options = selected.extract_options!.symbolize_keys
+ [ options[:selected] || selected , options[:disabled] ]
end
end
diff --git a/actionpack/test/controller/output_escaping_test.rb b/actionpack/test/controller/output_escaping_test.rb
index 43a8c05cda..f6913a2138 100644
--- a/actionpack/test/controller/output_escaping_test.rb
+++ b/actionpack/test/controller/output_escaping_test.rb
@@ -3,7 +3,7 @@ require 'abstract_unit'
class OutputEscapingTest < ActiveSupport::TestCase
test "escape_html shouldn't die when passed nil" do
- assert ERB::Util.h(nil).blank?
+ assert_blank ERB::Util.h(nil)
end
test "escapeHTML should escape strings" do
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 258f511f10..9037a13343 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -1113,7 +1113,7 @@ class RenderTest < ActionController::TestCase
def test_head_with_location_header
get :head_with_location_header
- assert @response.body.blank?
+ assert_blank @response.body
assert_equal "/foo", @response.headers["Location"]
assert_response :ok
end
@@ -1126,7 +1126,7 @@ class RenderTest < ActionController::TestCase
end
get :head_with_location_object
- assert @response.body.blank?
+ assert_blank @response.body
assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
assert_response :ok
end
@@ -1134,7 +1134,7 @@ class RenderTest < ActionController::TestCase
def test_head_with_custom_header
get :head_with_custom_header
- assert @response.body.blank?
+ assert_blank @response.body
assert_equal "something", @response.headers["X-Custom-Header"]
assert_response :ok
end
@@ -1414,7 +1414,7 @@ class EtagRenderTest < ActionController::TestCase
assert_equal 200, @response.status.to_i
assert_not_nil @response.last_modified
assert_nil @response.etag
- assert @response.body.present?
+ assert_present @response.body
end
def test_render_with_etag
@@ -1499,7 +1499,7 @@ class LastModifiedRenderTest < ActionController::TestCase
@request.if_modified_since = @last_modified
get :conditional_hello
assert_equal 304, @response.status.to_i
- assert @response.body.blank?, @response.body
+ assert_blank @response.body
assert_equal @last_modified, @response.headers['Last-Modified']
end
@@ -1514,7 +1514,7 @@ class LastModifiedRenderTest < ActionController::TestCase
@request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT'
get :conditional_hello
assert_equal 200, @response.status.to_i
- assert !@response.body.blank?
+ assert_present @response.body
assert_equal @last_modified, @response.headers['Last-Modified']
end
diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb
index be05ef6167..5ec760d4ea 100644
--- a/actionpack/test/controller/request_forgery_protection_test.rb
+++ b/actionpack/test/controller/request_forgery_protection_test.rb
@@ -251,7 +251,7 @@ class FreeCookieControllerTest < ActionController::TestCase
test 'should not emit a csrf-token meta tag' do
get :meta
- assert @response.body.blank?
+ assert_blank @response.body
end
end
diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb
index 7e7e4bd463..de2cab3e79 100644
--- a/actionpack/test/controller/test_test.rb
+++ b/actionpack/test/controller/test_test.rb
@@ -546,7 +546,7 @@ XML
assert_equal "bar", @request.params[:foo]
@request.recycle!
post :no_op
- assert @request.params[:foo].blank?
+ assert_blank @request.params[:foo]
end
def test_should_have_knowledge_of_client_side_cookie_state_even_if_they_are_not_set
diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb
index 5942950b15..2e6cf48406 100644
--- a/actionpack/test/controller/webservice_test.rb
+++ b/actionpack/test/controller/webservice_test.rb
@@ -29,7 +29,7 @@ class WebServiceTest < ActionController::IntegrationTest
def test_check_parameters
with_test_route_set do
get "/"
- assert @controller.response.body.blank?
+ assert_blank @controller.response.body
end
end
@@ -161,7 +161,7 @@ class WebServiceTest < ActionController::IntegrationTest
def test_use_xml_ximple_with_empty_request
with_test_route_set do
assert_nothing_raised { post "/", "", {'CONTENT_TYPE' => 'application/xml'} }
- assert @controller.response.body.blank?
+ assert_blank @controller.response.body
end
end
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index b04c1a42c0..cadae5d97f 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -232,6 +232,34 @@ class CookiesTest < ActionController::TestCase
assert_cookie_header "user_name=rizwanreza; domain=.nextangle.com; path=/"
end
+ def test_cookie_with_all_domain_option_using_a_non_standard_tld
+ @request.host = "two.subdomains.nextangle.local"
+ get :set_cookie_with_domain
+ assert_response :success
+ assert_cookie_header "user_name=rizwanreza; domain=.nextangle.local; path=/"
+ end
+
+ def test_cookie_with_all_domain_option_using_australian_style_tld
+ @request.host = "nextangle.com.au"
+ get :set_cookie_with_domain
+ assert_response :success
+ assert_cookie_header "user_name=rizwanreza; domain=.nextangle.com.au; path=/"
+ end
+
+ def test_cookie_with_all_domain_option_using_uk_style_tld
+ @request.host = "nextangle.co.uk"
+ get :set_cookie_with_domain
+ assert_response :success
+ assert_cookie_header "user_name=rizwanreza; domain=.nextangle.co.uk; path=/"
+ end
+
+ def test_cookie_with_all_domain_option_using_host_with_port
+ @request.host = "nextangle.local:3000"
+ get :set_cookie_with_domain
+ assert_response :success
+ assert_cookie_header "user_name=rizwanreza; domain=.nextangle.local; path=/"
+ end
+
def test_deleting_cookie_with_all_domain_option
get :delete_cookie_with_domain
assert_response :success
@@ -247,4 +275,4 @@ class CookiesTest < ActionController::TestCase
assert_equal expected.split("\n"), header
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/template/atom_feed_helper_test.rb b/actionpack/test/template/atom_feed_helper_test.rb
index 869ea22469..fb43a8f960 100644
--- a/actionpack/test/template/atom_feed_helper_test.rb
+++ b/actionpack/test/template/atom_feed_helper_test.rb
@@ -226,7 +226,7 @@ class AtomFeedTest < ActionController::TestCase
get :index, :id=>"provide_builder"
# because we pass in the non-default builder, the content generated by the
# helper should go 'nowhere'. Leaving the response body blank.
- assert @response.body.blank?
+ assert_blank @response.body
end
end
diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb
index 3dfaffbe97..bc04398afa 100644
--- a/actionpack/test/template/form_options_helper_test.rb
+++ b/actionpack/test/template/form_options_helper_test.rb
@@ -176,6 +176,68 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_collection_options_with_preselected_value_as_string_and_option_value_is_integer
+ albums = [ Album.new(1, "first","rap"), Album.new(2, "second","pop")]
+ assert_dom_equal(
+ %(<option selected="selected" value="1">rap</option>\n<option value="2">pop</option>),
+ options_from_collection_for_select(albums, "id", "genre", :selected => "1")
+ )
+ end
+
+ def test_collection_options_with_preselected_value_as_integer_and_option_value_is_string
+ albums = [ Album.new("1", "first","rap"), Album.new("2", "second","pop")]
+
+ assert_dom_equal(
+ %(<option selected="selected" value="1">rap</option>\n<option value="2">pop</option>),
+ options_from_collection_for_select(albums, "id", "genre", :selected => 1)
+ )
+ end
+
+ def test_collection_options_with_preselected_value_as_string_and_option_value_is_float
+ albums = [ Album.new(1.0, "first","rap"), Album.new(2.0, "second","pop")]
+
+ assert_dom_equal(
+ %(<option value="1.0">rap</option>\n<option value="2.0" selected="selected">pop</option>),
+ options_from_collection_for_select(albums, "id", "genre", :selected => "2.0")
+ )
+ end
+
+ def test_collection_options_with_preselected_value_as_nil
+ albums = [ Album.new(1.0, "first","rap"), Album.new(2.0, "second","pop")]
+
+ assert_dom_equal(
+ %(<option value="1.0">rap</option>\n<option value="2.0">pop</option>),
+ options_from_collection_for_select(albums, "id", "genre", :selected => nil)
+ )
+ end
+
+ def test_collection_options_with_disabled_value_as_nil
+ albums = [ Album.new(1.0, "first","rap"), Album.new(2.0, "second","pop")]
+
+ assert_dom_equal(
+ %(<option value="1.0">rap</option>\n<option value="2.0">pop</option>),
+ options_from_collection_for_select(albums, "id", "genre", :disabled => nil)
+ )
+ end
+
+ def test_collection_options_with_disabled_value_as_array
+ albums = [ Album.new(1.0, "first","rap"), Album.new(2.0, "second","pop")]
+
+ assert_dom_equal(
+ %(<option disabled="disabled" value="1.0">rap</option>\n<option disabled="disabled" value="2.0">pop</option>),
+ options_from_collection_for_select(albums, "id", "genre", :disabled => ["1.0", 2.0])
+ )
+ end
+
+ def test_collection_options_with_preselected_values_as_string_array_and_option_value_is_float
+ albums = [ Album.new(1.0, "first","rap"), Album.new(2.0, "second","pop"), Album.new(3.0, "third","country") ]
+
+ assert_dom_equal(
+ %(<option value="1.0" selected="selected">rap</option>\n<option value="2.0">pop</option>\n<option value="3.0" selected="selected">country</option>),
+ options_from_collection_for_select(albums, "id", "genre", ["1.0","3.0"])
+ )
+ end
+
def test_option_groups_from_collection_for_select
assert_dom_equal(
"<optgroup label=\"&lt;Africa&gt;\"><option value=\"&lt;sa&gt;\">&lt;South Africa&gt;</option>\n<option value=\"so\">Somalia</option></optgroup><optgroup label=\"Europe\"><option value=\"dk\" selected=\"selected\">Denmark</option>\n<option value=\"ie\">Ireland</option></optgroup>",
@@ -289,6 +351,10 @@ class FormOptionsHelperTest < ActionView::TestCase
opts
end
+ def test_time_zone_options_returns_html_safe_string
+ assert time_zone_options_for_select.html_safe?
+ end
+
def test_select
@post = Post.new
@post.category = "<mus>"
diff --git a/activemodel/lib/active_model/conversion.rb b/activemodel/lib/active_model/conversion.rb
index b998a59e81..ae0ab93e97 100644
--- a/activemodel/lib/active_model/conversion.rb
+++ b/activemodel/lib/active_model/conversion.rb
@@ -33,8 +33,11 @@ module ActiveModel
self
end
- # Returns an Enumerable of all (primary) key attributes or nil if
- # persisted? is false
+ # Returns an Enumerable of all key attributes if any is set, regardless
+ # if the object is persisted or not.
+ #
+ # Note the default implementation uses persisted? just because all objects
+ # in Ruby 1.8.x responds to :id.
def to_key
persisted? ? [id] : nil
end
@@ -42,7 +45,7 @@ module ActiveModel
# Returns a string representing the object's key suitable for use in URLs,
# or nil if persisted? is false
def to_param
- to_key ? to_key.join('-') : nil
+ persisted? ? to_key.join('-') : nil
end
end
end
diff --git a/activemodel/lib/active_model/lint.rb b/activemodel/lib/active_model/lint.rb
index 26eb4a3c41..d7a6da48ca 100644
--- a/activemodel/lib/active_model/lint.rb
+++ b/activemodel/lib/active_model/lint.rb
@@ -38,6 +38,7 @@ module ActiveModel
# not persisted?, then to_param should always return nil.
def test_to_param
assert model.respond_to?(:to_param), "The model should respond to to_param"
+ def model.to_key() [1] end
def model.persisted?() false end
assert model.to_param.nil?
end
diff --git a/activemodel/test/cases/mass_assignment_security_test.rb b/activemodel/test/cases/mass_assignment_security_test.rb
index c25b0fdf00..f84e55e8d9 100644
--- a/activemodel/test/cases/mass_assignment_security_test.rb
+++ b/activemodel/test/cases/mass_assignment_security_test.rb
@@ -25,13 +25,13 @@ class MassAssignmentSecurityTest < ActiveModel::TestCase
end
def test_mass_assignment_protection_inheritance
- assert LoosePerson.accessible_attributes.blank?
+ assert_blank LoosePerson.accessible_attributes
assert_equal Set.new([ 'credit_rating', 'administrator']), LoosePerson.protected_attributes
- assert LooseDescendant.accessible_attributes.blank?
+ assert_blank LooseDescendant.accessible_attributes
assert_equal Set.new([ 'credit_rating', 'administrator', 'phone_number']), LooseDescendant.protected_attributes
- assert LooseDescendantSecond.accessible_attributes.blank?
+ assert_blank LooseDescendantSecond.accessible_attributes
assert_equal Set.new([ 'credit_rating', 'administrator', 'phone_number', 'name']), LooseDescendantSecond.protected_attributes,
'Running attr_protected twice in one class should merge the protections'
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index 365fdeb55a..82d94b848a 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -3,6 +3,12 @@ module ActiveRecord
module PrimaryKey
extend ActiveSupport::Concern
+ # Returns this record's primary key value wrapped in an Array
+ # or nil if the record is a new_record?
+ def to_key
+ new_record? ? nil : [ id ]
+ end
+
module ClassMethods
# Defines the primary key field -- can be overridden in subclasses. Overwriting will negate any effect of the
# primary_key_prefix_type setting, though.
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 802921e181..9950387420 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -275,6 +275,7 @@ module ActiveRecord
rows = []
result.each { |row| rows << row }
result.free
+ @connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
rows
end
@@ -618,6 +619,7 @@ module ActiveRecord
rows = []
result.each_hash { |row| rows << row }
result.free
+ @connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
rows
end
diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb
index 1c4ecda5b5..01cc14b8d6 100644
--- a/activerecord/lib/active_record/session_store.rb
+++ b/activerecord/lib/active_record/session_store.rb
@@ -59,17 +59,15 @@ module ActiveRecord
end
def drop_table!
- connection.execute "DROP TABLE #{table_name}"
+ connection.drop_table table_name
end
def create_table!
- connection.execute <<-end_sql
- CREATE TABLE #{table_name} (
- id #{connection.type_to_sql(:primary_key)},
- #{connection.quote_column_name(session_id_column)} VARCHAR(255) UNIQUE,
- #{connection.quote_column_name(data_column_name)} TEXT
- )
- end_sql
+ connection.create_table(table_name) do |t|
+ t.string session_id_column, :limit => 255
+ t.text data_column_name
+ end
+ connection.add_index table_name, session_id_column, :unique => true
end
end
@@ -205,6 +203,7 @@ module ActiveRecord
class << self
alias :data_column_name :data_column
+ remove_method :connection
def connection
@@connection ||= ActiveRecord::Base.connection
end
diff --git a/activerecord/test/cases/adapters/mysql/connection_test.rb b/activerecord/test/cases/adapters/mysql/connection_test.rb
index 782aad72d6..f76a23a8ad 100644
--- a/activerecord/test/cases/adapters/mysql/connection_test.rb
+++ b/activerecord/test/cases/adapters/mysql/connection_test.rb
@@ -48,6 +48,7 @@ class MysqlConnectionTest < ActiveRecord::TestCase
def test_multi_results
rows = ActiveRecord::Base.connection.select_rows('CALL ten();')
assert_equal 10, rows[0][0].to_i, "ten() did not return 10 as expected: #{rows.inspect}"
+ assert @connection.active?, "Bad connection use by 'MysqlAdapter.select_rows'"
end
end
diff --git a/activerecord/test/cases/adapters/mysql/sp_test.rb b/activerecord/test/cases/adapters/mysql/sp_test.rb
new file mode 100644
index 0000000000..3ca2917ca4
--- /dev/null
+++ b/activerecord/test/cases/adapters/mysql/sp_test.rb
@@ -0,0 +1,15 @@
+require "cases/helper"
+require 'models/topic'
+
+class StoredProcedureTest < ActiveRecord::TestCase
+ fixtures :topics
+
+ # Test that MySQL allows multiple results for stored procedures
+ if Mysql.const_defined?(:CLIENT_MULTI_RESULTS)
+ def test_multi_results_from_find_by_sql
+ topics = Topic.find_by_sql 'CALL topics();'
+ assert_equal 1, topics.size
+ assert ActiveRecord::Base.connection.active?, "Bad connection use by 'MysqlAdapter.select'"
+ end
+ end
+end
diff --git a/activerecord/test/cases/aggregations_test.rb b/activerecord/test/cases/aggregations_test.rb
index 9e285e57dc..3e0e6dce2c 100644
--- a/activerecord/test/cases/aggregations_test.rb
+++ b/activerecord/test/cases/aggregations_test.rb
@@ -99,7 +99,7 @@ class AggregationsTest < ActiveRecord::TestCase
customers(:zaphod).save
customers(:zaphod).reload
assert_kind_of Address, customers(:zaphod).address
- assert customers(:zaphod).address.street.nil?
+ assert_nil customers(:zaphod).address.street
end
def test_nil_assignment_results_in_nil
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index a1ce9b1689..28234ebe49 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -22,7 +22,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
def test_belongs_to
Client.find(3).firm.name
assert_equal companies(:first_firm).name, Client.find(3).firm.name
- assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
+ assert_not_nil Client.find(3).firm, "Microsoft should have a firm"
end
def test_belongs_to_with_primary_key
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index ac2021c369..7e10a8ceeb 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -633,7 +633,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
# Should not be destroyed since the association is not dependent.
assert_nothing_raised do
- assert Client.find(client_id).firm.nil?
+ assert_nil Client.find(client_id).firm
end
end
@@ -658,7 +658,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal [client_id], Client.destroyed_client_ids[firm.id]
# Should be destroyed since the association is dependent.
- assert Client.find_by_id(client_id).nil?
+ assert_nil Client.find_by_id(client_id)
end
def test_clearing_an_exclusively_dependent_association_collection
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index 469a21b9bf..e959ed46cc 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -253,7 +253,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_dependence_with_missing_association_and_nullify
Account.destroy_all
firm = DependentFirm.find(:first)
- assert firm.account.nil?
+ assert_nil firm.account
firm.destroy
end
diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb
index fcdb81e92e..b83966e91c 100644
--- a/activerecord/test/cases/associations/join_model_test.rb
+++ b/activerecord/test/cases/associations/join_model_test.rb
@@ -427,8 +427,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
def test_has_many_through_uses_conditions_specified_on_the_has_many_association
author = Author.find(:first)
- assert !author.comments.blank?
- assert author.nonexistant_comments.blank?
+ assert_present author.comments
+ assert_blank author.nonexistant_comments
end
def test_has_many_through_uses_correct_attributes
diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb
index 5256ab8d11..312628a3e3 100644
--- a/activerecord/test/cases/method_scoping_test.rb
+++ b/activerecord/test/cases/method_scoping_test.rb
@@ -449,7 +449,7 @@ class NestedScopingTest < ActiveRecord::TestCase
Comment.send(:with_scope, :create => { :body => "Hey guys, nested scopes are broken. Please fix!" }) do
Comment.send(:with_exclusive_scope, :create => { :post_id => 1 }) do
assert_equal({:post_id => 1}, Comment.scoped.send(:scope_for_create))
- assert Comment.new.body.blank?
+ assert_blank Comment.new.body
comment = Comment.create :body => "Hey guys"
end
end
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 8d35f26b30..186bb55c01 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -806,6 +806,9 @@ if ActiveRecord::Base.connection.supports_migrations?
Topic.connection.change_column "topics", "written_on", :datetime, :null => false
Topic.reset_column_information
+
+ Topic.connection.change_column "topics", "written_on", :datetime, :null => true
+ Topic.reset_column_information
end
end
diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb
index c42dda2ccb..3d6975d0b5 100644
--- a/activerecord/test/cases/named_scope_test.rb
+++ b/activerecord/test/cases/named_scope_test.rb
@@ -480,8 +480,8 @@ class DynamicScopeTest < ActiveRecord::TestCase
end
def test_dynamic_scope_should_create_methods_after_hitting_method_missing
- assert Developer.methods.grep(/scoped_by_created_at/).blank?
+ assert_blank Developer.methods.grep(/scoped_by_created_at/)
Developer.scoped_by_created_at(nil)
- assert Developer.methods.grep(/scoped_by_created_at/).present?
+ assert_present Developer.methods.grep(/scoped_by_created_at/)
end
end
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index 5cdcb05902..63d8c7d1c1 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -11,7 +11,7 @@ class PrimaryKeysTest < ActiveRecord::TestCase
def test_to_key_with_default_primary_key
topic = Topic.new
- assert topic.to_key.nil?
+ assert_nil topic.to_key
topic = Topic.find(1)
assert_equal [1], topic.to_key
end
@@ -26,7 +26,7 @@ class PrimaryKeysTest < ActiveRecord::TestCase
def test_to_key_with_primary_key_after_destroy
topic = Topic.find(1)
topic.destroy
- assert_equal nil, topic.to_key
+ assert_equal [1], topic.to_key
end
def test_integer_key
diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/relation_scoping_test.rb
index 9494990b04..d56e5a7999 100644
--- a/activerecord/test/cases/relation_scoping_test.rb
+++ b/activerecord/test/cases/relation_scoping_test.rb
@@ -209,7 +209,7 @@ class NestedRelationScopingTest < ActiveRecord::TestCase
def test_nested_exclusive_scope_for_create
comment = Comment.create_with(:body => "Hey guys, nested scopes are broken. Please fix!").scoping do
Comment.unscoped.create_with(:post_id => 1).scoping do
- assert Comment.new.body.blank?
+ assert_blank Comment.new.body
Comment.create :body => "Hey guys"
end
end
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index bd6e216c62..aa75aa27d4 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -411,7 +411,7 @@ class RelationTest < ActiveRecord::TestCase
def test_find_in_empty_array
authors = Author.scoped.where(:id => [])
- assert authors.all.blank?
+ assert_blank authors.all
end
def test_exists
@@ -486,7 +486,7 @@ class RelationTest < ActiveRecord::TestCase
def test_relation_merging_with_locks
devs = Developer.lock.where("salary >= 80000").order("id DESC") & Developer.limit(2)
- assert devs.locked.present?
+ assert_present devs.locked
end
def test_relation_merging_with_preload
diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb
index 597b954d84..fce27d8972 100644
--- a/activerecord/test/cases/timestamp_test.rb
+++ b/activerecord/test/cases/timestamp_test.rb
@@ -84,6 +84,22 @@ class TimestampTest < ActiveRecord::TestCase
Pet.belongs_to :owner, :touch => true
end
+ def test_touching_a_record_with_a_belongs_to_that_uses_a_counter_cache_should_update_the_parent
+ Pet.belongs_to :owner, :counter_cache => :use_count, :touch => true
+
+ pet = Pet.first
+ owner = pet.owner
+ owner.update_attribute(:happy_at, (time = 3.days.ago))
+ previously_owner_updated_at = owner.updated_at
+
+ pet.name = "I'm a parrot"
+ pet.save
+
+ assert_not_equal previously_owner_updated_at, pet.owner.updated_at
+ ensure
+ Pet.belongs_to :owner, :touch => true
+ end
+
def test_touching_a_record_touches_parent_record_and_grandparent_record
Toy.belongs_to :pet, :touch => true
Pet.belongs_to :owner, :touch => true
diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb
index d72c4bf7c4..cc146f5574 100644
--- a/activerecord/test/cases/transaction_callbacks_test.rb
+++ b/activerecord/test/cases/transaction_callbacks_test.rb
@@ -272,7 +272,7 @@ class TransactionObserverCallbacksTest < ActiveRecord::TestCase
topic = TopicWithObserverAttached.new
topic.save!
- assert topic.history, [:"TopicWithObserverAttachedObserver#after_commit"]
+ assert_equal topic.history, [:"TopicWithObserverAttachedObserver#after_commit"]
end
def test_after_rollback_called
@@ -283,6 +283,6 @@ class TransactionObserverCallbacksTest < ActiveRecord::TestCase
raise ActiveRecord::Rollback
end
- assert topic.history, [:"TopicWithObserverObserver#after_rollback"]
+ assert_equal topic.history, [:"TopicWithObserverObserver#after_rollback"]
end
end
diff --git a/activerecord/test/connections/native_oracle/connection.rb b/activerecord/test/connections/native_oracle/connection.rb
index bb4040058f..00164466f2 100644
--- a/activerecord/test/connections/native_oracle/connection.rb
+++ b/activerecord/test/connections/native_oracle/connection.rb
@@ -1,10 +1,5 @@
-# gem "rsim-activerecord-oracle_enhanced-adapter"
-# gem "activerecord-oracle_enhanced-adapter", ">=1.2.1"
-# uses local copy of oracle_enhanced adapter
-$:.unshift("../../oracle-enhanced/lib")
+# uses oracle_enhanced adapter in ENV['ORACLE_ENHANCED_PATH'] or from github.com/rsim/oracle-enhanced.git
require 'active_record/connection_adapters/oracle_enhanced_adapter'
-# gem "activerecord-jdbc-adapter"
-# require 'active_record/connection_adapters/jdbc_adapter'
# otherwise failed with silence_warnings method missing exception
require 'active_support/core_ext/kernel/reporting'
diff --git a/activerecord/test/schema/mysql_specific_schema.rb b/activerecord/test/schema/mysql_specific_schema.rb
index c78d99f4af..30e1c5a167 100644
--- a/activerecord/test/schema/mysql_specific_schema.rb
+++ b/activerecord/test/schema/mysql_specific_schema.rb
@@ -21,4 +21,15 @@ BEGIN
END
SQL
+ ActiveRecord::Base.connection.execute <<-SQL
+DROP PROCEDURE IF EXISTS topics;
+SQL
+
+ ActiveRecord::Base.connection.execute <<-SQL
+CREATE PROCEDURE topics() SQL SECURITY INVOKER
+BEGIN
+ select * from topics limit 1;
+END
+SQL
+
end
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb
index 7585137aca..baefa9cae4 100644
--- a/activesupport/lib/active_support/core_ext/array/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -26,7 +26,7 @@ class Array
when 0
""
when 1
- self[0].to_s
+ self[0].to_s.dup
when 2
"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
else
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb
index 79d5c40e5f..688cba03db 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -72,6 +72,7 @@ class Class
remove_possible_method(:#{name})
define_method(:#{name}) { val }
end
+ val
end
def #{name}
diff --git a/activesupport/lib/active_support/core_ext/object.rb b/activesupport/lib/active_support/core_ext/object.rb
index d671da6711..790a26f5c1 100644
--- a/activesupport/lib/active_support/core_ext/object.rb
+++ b/activesupport/lib/active_support/core_ext/object.rb
@@ -2,7 +2,6 @@ require 'active_support/core_ext/object/acts_like'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/duplicable'
require 'active_support/core_ext/object/try'
-require 'active_support/core_ext/object/returning'
require 'active_support/core_ext/object/conversions'
require 'active_support/core_ext/object/instance_variables'
diff --git a/activesupport/lib/active_support/core_ext/object/returning.rb b/activesupport/lib/active_support/core_ext/object/returning.rb
deleted file mode 100644
index c401992ccc..0000000000
--- a/activesupport/lib/active_support/core_ext/object/returning.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-class Object
- # Returns +value+ after yielding +value+ to the block. This simplifies the
- # process of constructing an object, performing work on the object, and then
- # returning the object from a method. It is a Ruby-ized realization of the K
- # combinator, courtesy of Mikael Brockman.
- #
- # ==== Examples
- #
- # # Without returning
- # def foo
- # values = []
- # values << "bar"
- # values << "baz"
- # return values
- # end
- #
- # foo # => ['bar', 'baz']
- #
- # # returning with a local variable
- # def foo
- # returning values = [] do
- # values << 'bar'
- # values << 'baz'
- # end
- # end
- #
- # foo # => ['bar', 'baz']
- #
- # # returning with a block argument
- # def foo
- # returning [] do |values|
- # values << 'bar'
- # values << 'baz'
- # end
- # end
- #
- # foo # => ['bar', 'baz']
- def returning(value)
- ActiveSupport::Deprecation.warn('Object#returning has been deprecated in favor of Object#tap.', caller)
- yield(value)
- value
- end
-end \ No newline at end of file
diff --git a/activesupport/lib/active_support/log_subscriber.rb b/activesupport/lib/active_support/log_subscriber.rb
index 49f7513193..df335af841 100644
--- a/activesupport/lib/active_support/log_subscriber.rb
+++ b/activesupport/lib/active_support/log_subscriber.rb
@@ -31,19 +31,6 @@ module ActiveSupport
# all logs when the request finishes (via action_dispatch.callback notification) in
# a Rails environment.
class LogSubscriber
- mattr_accessor :colorize_logging
- self.colorize_logging = true
-
- class_attribute :logger
-
- class << self
- remove_method :logger
- end
-
- def self.logger
- @logger ||= Rails.logger if defined?(Rails)
- end
-
# Embed in a String to clear all previous ANSI sequences.
CLEAR = "\e[0m"
BOLD = "\e[1m"
@@ -58,32 +45,44 @@ module ActiveSupport
CYAN = "\e[36m"
WHITE = "\e[37m"
- def self.attach_to(namespace, log_subscriber=new, notifier=ActiveSupport::Notifications)
- log_subscribers << log_subscriber
- @@flushable_loggers = nil
+ mattr_accessor :colorize_logging
+ self.colorize_logging = true
- log_subscriber.public_methods(false).each do |event|
- next if 'call' == event.to_s
+ class_attribute :logger
- notifier.subscribe("#{event}.#{namespace}", log_subscriber)
+ class << self
+ remove_method :logger
+ def logger
+ @logger ||= Rails.logger if defined?(Rails)
end
- end
- def self.log_subscribers
- @@log_subscribers ||= []
- end
+ def attach_to(namespace, log_subscriber=new, notifier=ActiveSupport::Notifications)
+ log_subscribers << log_subscriber
+ @@flushable_loggers = nil
- def self.flushable_loggers
- @@flushable_loggers ||= begin
- loggers = log_subscribers.map(&:logger)
- loggers.uniq!
- loggers.select { |l| l.respond_to?(:flush) }
+ log_subscriber.public_methods(false).each do |event|
+ next if 'call' == event.to_s
+
+ notifier.subscribe("#{event}.#{namespace}", log_subscriber)
+ end
end
- end
- # Flush all log_subscribers' logger.
- def self.flush_all!
- flushable_loggers.each(&:flush)
+ def log_subscribers
+ @@log_subscribers ||= []
+ end
+
+ def flushable_loggers
+ @@flushable_loggers ||= begin
+ loggers = log_subscribers.map(&:logger)
+ loggers.uniq!
+ loggers.select { |l| l.respond_to?(:flush) }
+ end
+ end
+
+ # Flush all log_subscribers' logger.
+ def flush_all!
+ flushable_loggers.each(&:flush)
+ end
end
def call(message, *args)
diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb
index 8c68f42781..a4e0361a32 100644
--- a/activesupport/lib/active_support/testing/assertions.rb
+++ b/activesupport/lib/active_support/testing/assertions.rb
@@ -67,15 +67,17 @@ module ActiveSupport
# Test if an expression is blank. Passes if object.blank? is true.
#
# assert_blank [] # => true
- def assert_blank(object)
- assert object.blank?, "#{object.inspect} is not blank"
+ def assert_blank(object, message=nil)
+ message ||= "#{object.inspect} is not blank"
+ assert object.blank?, message
end
# Test if an expression is not blank. Passes if object.present? is true.
#
# assert_present {:data => 'x' } # => true
- def assert_present(object)
- assert object.present?, "#{object.inspect} is blank"
+ def assert_present(object, message=nil)
+ message ||= "#{object.inspect} is blank"
+ assert object.present?, message
end
end
end
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index b79a7bbaec..28ef695a4b 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -649,12 +649,12 @@ class CacheStoreLoggerTest < ActiveSupport::TestCase
def test_logging
@cache.fetch('foo') { 'bar' }
- assert @buffer.string.present?
+ assert_present @buffer.string
end
def test_mute_logging
@cache.mute { @cache.fetch('foo') { 'bar' } }
- assert @buffer.string.blank?
+ assert_blank @buffer.string
end
end
diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb
index d14ae39737..d7ab3ce605 100644
--- a/activesupport/test/core_ext/array_ext_test.rb
+++ b/activesupport/test/core_ext/array_ext_test.rb
@@ -82,6 +82,11 @@ class ArrayExtToSentenceTests < Test::Unit::TestCase
assert_equal "one", ['one'].to_sentence
end
+ def test_one_element_not_same_object
+ elements = ["one"]
+ assert_not_equal elements[0].object_id, elements.to_sentence.object_id
+ end
+
def test_one_non_string_element
assert_equal '1', [1].to_sentence
end
diff --git a/activesupport/test/core_ext/class/attribute_test.rb b/activesupport/test/core_ext/class/attribute_test.rb
index 24aa5c0eba..d58b60482b 100644
--- a/activesupport/test/core_ext/class/attribute_test.rb
+++ b/activesupport/test/core_ext/class/attribute_test.rb
@@ -65,4 +65,9 @@ class ClassAttributeTest < ActiveSupport::TestCase
object.singleton_class.setting = 'foo'
assert_equal 'foo', object.setting
end
+
+ test 'setter returns set value' do
+ val = @klass.send(:setting=, 1)
+ assert_equal 1, val
+ end
end
diff --git a/ci/ci_build.rb b/ci/ci_build.rb
index f9933cb922..e75f91cd3b 100755
--- a/ci/ci_build.rb
+++ b/ci/ci_build.rb
@@ -89,6 +89,14 @@ end
cd "#{root_dir}/activerecord" do
puts
+ puts "[CruiseControl] Building ActiveRecord with MySQL2"
+ puts
+ build_results[:activerecord_mysql2] = rake 'mysql:rebuild_databases', 'mysql2:test'
+ # build_results[:activerecord_mysql2_isolated] = rake 'mysql:rebuild_databases', 'mysql2:isolated_test'
+end
+
+cd "#{root_dir}/activerecord" do
+ puts
puts "[CruiseControl] Building ActiveRecord with PostgreSQL"
puts
build_results[:activerecord_postgresql8] = rake 'postgresql:rebuild_databases', 'postgresql:test'
diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile
index 270fbe76d2..e68a82e9db 100644
--- a/railties/guides/source/getting_started.textile
+++ b/railties/guides/source/getting_started.textile
@@ -492,7 +492,7 @@ TIP: Unlike the development web server, the console does not automatically load
h4. Listing All Posts
-The easiest place to start looking at functionality is with the code that lists all posts. Open the file +app/controllers/posts_controller.rb + and look at the +index+ action:
+The easiest place to start looking at functionality is with the code that lists all posts. Open the file +app/controllers/posts_controller.rb+ and look at the +index+ action:
<ruby>
def index
@@ -505,7 +505,7 @@ def index
end
</ruby>
-+Post.all+ calls the +Post+ model to return all of the posts currently in the database. The result of this call is an array containing the posts which has been saved in an instance variable called +@posts+.
++Post.all+ calls the +Post+ model to return all of the posts currently in the database. The result of this call is an array of posts that we store in a instance variable called +@posts+.
TIP: For more information on finding records with Active Record, see "Active Record Query Interface":active_record_querying.html.
@@ -552,7 +552,7 @@ TIP: For more details on the rendering process, see "Layouts and Rendering in Ra
h4. Customizing the Layout
-The view is only part of the story of how HTML is displayed in your web browser. Rails also has the concept of +layouts+, which are containers for views. When Rails renders a view to the browser, it does so by putting the view's HTML into a layout's HTML. In previous versions of Rails, the +rails generate scaffold+ command would automatically create a controller specific layout, like +app/views/layouts/posts.html.erb+, for the posts controller. However this has been changed in Rails 3.0. A application specific +layout+ is used for all the controllers and can be found in +app/views/layouts/application.html.erb+. Open this layout in your editor and modify the +body+ tag:
+The view is only part of the story of how HTML is displayed in your web browser. Rails also has the concept of +layouts+, which are containers for views. When Rails renders a view to the browser, it does so by putting the view's HTML into a layout's HTML. In previous versions of Rails, the +rails generate scaffold+ command would automatically create a controller specific layout, like +app/views/layouts/posts.html.erb+, for the posts controller. However this has been changed in Rails 3.0. An application specific +layout+ is used for all the controllers and can be found in +app/views/layouts/application.html.erb+. Open this layout in your editor and modify the +body+ tag:
<erb>
<!DOCTYPE html>
@@ -668,7 +668,7 @@ The +create+ action instantiates a new Post object from the data supplied by the
If the post was not successfully saved, due to a validation error, then the controller returns the user back to the +new+ action with any error messages so that the user has the chance to fix the error and try again.
-The "Post was successfully created" message is stored inside of the Rails +flash+ hash, (usually just called the Flash) so that messages can be carried over to another action, providing the user with useful information on the status of their request. In the case of +create+, the user never actually sees any page rendered during the Post creation process, because it immediately redirects to the new Post as soon Rails saves the record. The Flash carries over a message to the next action, so that when the user is redirected back to the +show+ action, they are presented with a message saying "Post was successfully created."
+The "Post was successfully created." message is stored inside of the Rails +flash+ hash, (usually just called _the flash_) so that messages can be carried over to another action, providing the user with useful information on the status of their request. In the case of +create+, the user never actually sees any page rendered during the Post creation process, because it immediately redirects to the new Post as soon Rails saves the record. The Flash carries over a message to the next action, so that when the user is redirected back to the +show+ action, they are presented with a message saying "Post was successfully created."
h4. Showing an Individual Post
diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile
index d92c66cfd2..7e1b0c2e32 100644
--- a/railties/guides/source/routing.textile
+++ b/railties/guides/source/routing.textile
@@ -313,7 +313,7 @@ To add a member route, just add a +member+ block into the resource block:
<ruby>
resources :photos do
member do
- get :preview
+ get 'preview'
end
end
</ruby>
@@ -324,7 +324,7 @@ Within the block of member routes, each route name specifies the HTTP verb that
<ruby>
resources :photos do
- get :preview, :on => :member
+ get 'preview', :on => :member
end
</ruby>
@@ -335,7 +335,7 @@ To add a route to the collection:
<ruby>
resources :photos do
collection do
- get :search
+ get 'search'
end
end
</ruby>
@@ -346,7 +346,7 @@ Just as with member routes, you can pass +:on+ to a route:
<ruby>
resources :photos do
- get :search, :on => :collection
+ get 'search', :on => :collection
end
</ruby>
@@ -516,6 +516,22 @@ match 'photos/*other' => 'photos#unknown'
This route would match +photos/12+ or +/photos/long/path/to/12+, setting +params[:other]+ to +"12"+ or +"long/path/to/12"+.
+Wildcard segments do not need to be last in a route. For example
+
+<ruby>
+match 'books/*section/:title' => 'books#show'
+</ruby>
+
+would match +books/some/section/last-words-a-memoir+ with +params[:section]+ equals +"some/section"+, and +params[:title]+ equals +"last-words-a-memoir"+.
+
+Techincally a route can have even more than one wildard segment indeed, the matcher assigns segments to parameters in an intuitive way. For instance
+
+<ruby>
+match '*a/foo/*b' => 'test#index'
+</ruby>
+
+would match +zoo/woo/foo/bar/baz+ with +params[:a]+ equals +"zoo/woo"+, and +params[:b]+ equals +"bar/baz"+.
+
h4. Redirection
You can redirect any path to another path using the +redirect+ helper in your router:
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 465851c0e6..c3418e0d80 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -16,9 +16,9 @@ module Rails
def initialize(*)
super
+ self.encoding = "utf-8"
@allow_concurrency = false
@consider_all_requests_local = false
- @encoding = "utf-8"
@filter_parameters = []
@dependency_loading = true
@serve_static_assets = true
diff --git a/railties/lib/rails/generators/rails/app/templates/config/routes.rb b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
index d42cf3bfdf..3e35d81a69 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
@@ -16,12 +16,12 @@
# Sample resource route with options:
# resources :products do
# member do
- # get :short
- # post :toggle
+ # get 'short'
+ # post 'toggle'
# end
#
# collection do
- # get :sold
+ # get 'sold'
# end
# end
@@ -35,7 +35,7 @@
# resources :products do
# resources :comments
# resources :sales do
- # get :recent, :on => :collection
+ # get 'recent', :on => :collection
# end
# end
diff --git a/railties/lib/rails/tasks/routes.rake b/railties/lib/rails/tasks/routes.rake
index a99232c4be..c0a2fe38bd 100644
--- a/railties/lib/rails/tasks/routes.rake
+++ b/railties/lib/rails/tasks/routes.rake
@@ -1,21 +1,35 @@
desc 'Print out all defined routes in match order, with names. Target specific controller with CONTROLLER=x.'
task :routes => :environment do
Rails.application.reload_routes!
- all_routes = ENV['CONTROLLER'] ? Rails.application.routes.routes.select { |route| route.defaults[:controller] == ENV['CONTROLLER'] } : Rails.application.routes.routes
+
+ all_routes = Rails.application.routes.routes
+ named_routes = Rails.application.routes.named_routes.routes
+
+ if ENV['CONTROLLER']
+ all_routes = all_routes.select{ |route| route.defaults[:controller] == ENV['CONTROLLER'] }
+ end
+
routes = all_routes.collect do |route|
# TODO: The :index method is deprecated in 1.9 in favor of :key
# but we don't have :key in 1.8.7. We can remove this check when
# stop supporting 1.8.x
- key_method = Hash.method_defined?('key') ? 'key' : 'index'
- name = Rails.application.routes.named_routes.routes.send(key_method, route).to_s
- reqs = route.requirements.empty? ? "" : route.requirements.inspect
+ key = Hash.method_defined?('key') ? 'key' : 'index'
+ name = named_routes.send(key, route).to_s
+
+ reqs = route.requirements.dup
+ reqs[:to] = route.app unless route.app.is_a?(ActionDispatch::Routing::RouteSet::Dispatcher)
+ reqs = reqs.empty? ? "" : reqs.inspect
+
{:name => name, :verb => route.verb.to_s, :path => route.path, :reqs => reqs}
end
- routes.reject!{ |r| r[:path] == "/rails/info/properties" } # skip the route if it's internal info route
- name_width = routes.collect {|r| r[:name]}.collect {|n| n.length}.max
- verb_width = routes.collect {|r| r[:verb]}.collect {|v| v.length}.max
- path_width = routes.collect {|r| r[:path]}.collect {|s| s.length}.max
+
+ routes.reject! { |r| r[:path] == "/rails/info/properties" } # Skip the route if it's internal info route
+
+ name_width = routes.map{ |r| r[:name] }.map(&:length).max
+ verb_width = routes.map{ |r| r[:verb] }.map(&:length).max
+ path_width = routes.map{ |r| r[:path] }.map(&:length).max
+
routes.each do |r|
puts "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
end
-end
+end \ No newline at end of file
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 9928ee2c52..d63d25b42e 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -172,17 +172,27 @@ module ApplicationTests
assert $prepared
end
+ def assert_utf8
+ if RUBY_VERSION < '1.9'
+ assert_equal "UTF8", $KCODE
+ else
+ assert_equal Encoding::UTF_8, Encoding.default_external
+ assert_equal Encoding::UTF_8, Encoding.default_internal
+ end
+ end
+
+ test "skipping config.encoding still results in 'utf-8' as the default" do
+ require "#{app_path}/config/application"
+ assert_utf8
+ end
+
test "config.encoding sets the default encoding" do
add_to_config <<-RUBY
config.encoding = "utf-8"
RUBY
require "#{app_path}/config/application"
-
- unless RUBY_VERSION < '1.9'
- assert_equal Encoding::UTF_8, Encoding.default_external
- assert_equal Encoding::UTF_8, Encoding.default_internal
- end
+ assert_utf8
end
test "config.paths.public sets Rails.public_path" do