aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile5
-rw-r--r--actionmailer/CHANGELOG4
-rw-r--r--actionpack/CHANGELOG4
-rw-r--r--actionpack/lib/abstract_controller/callbacks.rb32
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb2
-rw-r--r--actionpack/lib/action_controller/metal/testing.rb9
-rw-r--r--actionpack/lib/action_controller/test_case.rb5
-rw-r--r--actionpack/lib/action_dispatch/routing/route.rb3
-rw-r--r--actionpack/lib/action_dispatch/testing/test_process.rb2
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb8
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb3
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb7
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb31
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb7
-rw-r--r--actionpack/test/activerecord/active_record_store_test.rb20
-rw-r--r--actionpack/test/controller/filters_test.rb81
-rw-r--r--actionpack/test/controller/mime_responds_test.rb16
-rw-r--r--actionpack/test/controller/new_base/bare_metal_test.rb7
-rw-r--r--actionpack/test/controller/new_base/render_template_test.rb10
-rw-r--r--actionpack/test/dispatch/cookies_test.rb18
-rw-r--r--actionpack/test/fixtures/layouts/_partial_and_yield.erb2
-rw-r--r--actionpack/test/fixtures/layouts/_yield_only.erb1
-rw-r--r--actionpack/test/fixtures/layouts/_yield_with_params.erb1
-rw-r--r--actionpack/test/fixtures/layouts/yield_with_render_partial_inside.erb2
-rw-r--r--actionpack/test/fixtures/test/_partial_with_partial.erb2
-rw-r--r--actionpack/test/lib/controller/fake_models.rb10
-rw-r--r--actionpack/test/template/asset_tag_helper_test.rb11
-rw-r--r--actionpack/test/template/capture_helper_test.rb10
-rw-r--r--actionpack/test/template/date_helper_test.rb41
-rw-r--r--actionpack/test/template/form_helper_test.rb21
-rw-r--r--actionpack/test/template/number_helper_i18n_test.rb5
-rw-r--r--actionpack/test/template/number_helper_test.rb4
-rw-r--r--actionpack/test/template/render_test.rb30
-rw-r--r--actionpack/test/template/url_helper_test.rb7
-rw-r--r--activemodel/CHANGELOG4
-rw-r--r--activemodel/test/cases/serializeration/xml_serialization_test.rb7
-rw-r--r--activerecord/CHANGELOG29
-rw-r--r--activerecord/activerecord.gemspec2
-rw-r--r--activerecord/lib/active_record/aggregations.rb2
-rw-r--r--activerecord/lib/active_record/associations.rb40
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb20
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb8
-rw-r--r--activerecord/lib/active_record/associations/belongs_to_association.rb6
-rw-r--r--activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_one_association.rb12
-rw-r--r--activerecord/lib/active_record/associations/has_one_through_association.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb7
-rw-r--r--activerecord/lib/active_record/autosave_association.rb14
-rw-r--r--activerecord/lib/active_record/base.rb18
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb16
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb22
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb2
-rw-r--r--activerecord/lib/active_record/locking/pessimistic.rb2
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb2
-rw-r--r--activerecord/lib/active_record/persistence.rb11
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb10
-rw-r--r--activerecord/lib/active_record/session_store.rb9
-rw-r--r--activerecord/lib/active_record/transactions.rb12
-rw-r--r--activerecord/lib/active_record/validations.rb2
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb44
-rw-r--r--activerecord/test/cases/adapters/mysql/connection_test.rb26
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb18
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb4
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb24
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb12
-rw-r--r--activerecord/test/cases/associations/cascaded_eager_loading_test.rb2
-rw-r--r--activerecord/test/cases/associations/eager_test.rb4
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb26
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb12
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb4
-rw-r--r--activerecord/test/cases/associations/join_model_test.rb16
-rw-r--r--activerecord/test/cases/autosave_association_test.rb86
-rw-r--r--activerecord/test/cases/base_test.rb12
-rw-r--r--activerecord/test/cases/finder_test.rb42
-rw-r--r--activerecord/test/cases/helper.rb10
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb24
-rw-r--r--activerecord/test/cases/persistence_test.rb9
-rw-r--r--activerecord/test/cases/relations_test.rb23
-rw-r--r--activerecord/test/cases/session_store/sql_bypass.rb4
-rw-r--r--activerecord/test/cases/transactions_test.rb16
-rw-r--r--activerecord/test/connections/native_oracle/connection.rb12
-rw-r--r--activerecord/test/models/eye.rb2
-rw-r--r--activerecord/test/models/pirate.rb2
-rw-r--r--activerecord/test/models/subject.rb2
-rw-r--r--activerecord/test/models/topic.rb2
-rw-r--r--activeresource/CHANGELOG4
-rw-r--r--activesupport/CHANGELOG4
-rw-r--r--activesupport/lib/active_support/cache/file_store.rb7
-rw-r--r--activesupport/lib/active_support/core_ext/cgi.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb19
-rw-r--r--activesupport/lib/active_support/core_ext/object/instance_variables.rb31
-rw-r--r--activesupport/lib/active_support/hash_with_indifferent_access.rb6
-rw-r--r--activesupport/lib/active_support/ordered_hash.rb2
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb2
-rw-r--r--activesupport/lib/active_support/xml_mini.rb6
-rw-r--r--activesupport/test/caching_test.rb9
-rw-r--r--activesupport/test/core_ext/cgi_ext_test.rb15
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb24
-rw-r--r--activesupport/test/core_ext/object_and_class_ext_test.rb31
-rw-r--r--activesupport/test/core_ext/time_with_zone_test.rb11
-rw-r--r--activesupport/test/ordered_hash_test.rb8
-rw-r--r--activesupport/test/test_xml_mini.rb16
-rw-r--r--railties/guides/source/active_support_core_extensions.textile33
-rw-r--r--railties/guides/source/api_documentation_guidelines.textile14
-rw-r--r--railties/lib/rails/application.rb1
-rw-r--r--railties/lib/rails/cli.rb3
-rw-r--r--railties/lib/rails/engine.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb4
-rw-r--r--railties/lib/rails/generators/resource_helpers.rb2
-rw-r--r--railties/lib/rails/info.rb1
-rw-r--r--railties/railties.gemspec2
-rw-r--r--railties/test/application/rake_test.rb9
-rw-r--r--railties/test/generators/resource_generator_test.rb5
117 files changed, 861 insertions, 541 deletions
diff --git a/Gemfile b/Gemfile
index 66a446a177..3aaf9a6123 100644
--- a/Gemfile
+++ b/Gemfile
@@ -31,6 +31,11 @@ platforms :mri_18 do
gem 'ruby-prof'
end
+platforms :mri_19 do
+ # TODO: Remove the conditional when ruby-debug19 supports Ruby >= 1.9.3
+ gem "ruby-debug19" if RUBY_VERSION < "1.9.3"
+end
+
platforms :ruby do
gem 'json'
gem 'yajl-ruby'
diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG
index 9c073dce1f..167c1da9c5 100644
--- a/actionmailer/CHANGELOG
+++ b/actionmailer/CHANGELOG
@@ -2,6 +2,10 @@
* No changes
+*Rails 3.0.2 (unreleased)*
+
+* No changes
+
*Rails 3.0.1 (October 15, 2010)*
* No Changes, just a version bump.
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 2d133ca0b2..db02beee35 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -23,6 +23,10 @@
* Add Rack::Cache to the default stack. Create a Rails store that delegates to the Rails cache, so by default, whatever caching layer you are using will be used for HTTP caching. Note that Rack::Cache will be used if you use #expires_in, #fresh_when or #stale with :public => true. Otherwise, the caching rules will apply to the browser only. [Yehuda Katz, Carl Lerche]
+*Rails 3.0.2 (unreleased)*
+
+* The helper number_to_currency accepts a new :negative_format option to be able to configure how to render negative amounts. [Don Wilson]
+
*Rails 3.0.1 (October 15, 2010)*
* No Changes, just a version bump.
diff --git a/actionpack/lib/abstract_controller/callbacks.rb b/actionpack/lib/abstract_controller/callbacks.rb
index 7b0d80614d..f169ab7c3a 100644
--- a/actionpack/lib/abstract_controller/callbacks.rb
+++ b/actionpack/lib/abstract_controller/callbacks.rb
@@ -81,27 +81,29 @@ module AbstractController
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
# Append a before, after or around filter. See _insert_callbacks
# for details on the allowed parameters.
- def #{filter}_filter(*names, &blk) # def before_filter(*names, &blk)
- _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options}
- set_callback(:process_action, :#{filter}, name, options) # set_callback(:process_action, :before_filter, name, options)
- end # end
- end # end
+ def #{filter}_filter(*names, &blk)
+ _insert_callbacks(names, blk) do |name, options|
+ options[:if] = (Array.wrap(options[:if]) << "!halted") if #{filter == :after}
+ set_callback(:process_action, :#{filter}, name, options)
+ end
+ end
# Prepend a before, after or around filter. See _insert_callbacks
# for details on the allowed parameters.
- def prepend_#{filter}_filter(*names, &blk) # def prepend_before_filter(*names, &blk)
- _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
- set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true))
- end # end
- end # end
+ def prepend_#{filter}_filter(*names, &blk)
+ _insert_callbacks(names, blk) do |name, options|
+ options[:if] = (Array.wrap(options[:if]) << "!halted") if #{filter == :after}
+ set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true))
+ end
+ end
# Skip a before, after or around filter. See _insert_callbacks
# for details on the allowed parameters.
- def skip_#{filter}_filter(*names, &blk) # def skip_before_filter(*names, &blk)
- _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
- skip_callback(:process_action, :#{filter}, name, options) # skip_callback(:process_action, :before, name, options)
- end # end
- end # end
+ def skip_#{filter}_filter(*names, &blk)
+ _insert_callbacks(names, blk) do |name, options|
+ skip_callback(:process_action, :#{filter}, name, options)
+ end
+ end
# *_filter is the same as append_*_filter
alias_method :append_#{filter}_filter, :#{filter}_filter
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index c6d4c6d936..f7dd0dcb69 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -227,7 +227,7 @@ module ActionController #:nodoc:
"controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
if response = retrieve_response_from_mimes(&block)
- options = resources.extract_options!
+ options = resources.size == 1 ? {} : resources.extract_options!
options.merge!(:default_response => response)
(options.delete(:responder) || self.class.responder).call(self, resources, options)
end
diff --git a/actionpack/lib/action_controller/metal/testing.rb b/actionpack/lib/action_controller/metal/testing.rb
index 4b8c452d50..f4efeb33ba 100644
--- a/actionpack/lib/action_controller/metal/testing.rb
+++ b/actionpack/lib/action_controller/metal/testing.rb
@@ -14,18 +14,9 @@ module ActionController
cookies.write(@_response)
end
@_response.prepare!
- set_test_assigns
ret
end
- def set_test_assigns
- @assigns = {}
- (instance_variable_names - self.class.protected_instance_variables).each do |var|
- name, value = var[1..-1], instance_variable_get(var)
- @assigns[name] = value
- end
- end
-
# TODO : Rewrite tests using controller.headers= to use Rack env
def headers=(new_headers)
@_response ||= ActionDispatch::Response.new
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 0c26071379..2b2f647d32 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -411,8 +411,9 @@ module ActionController
@controller.request = @request
@controller.params.merge!(parameters)
build_request_uri(action, parameters)
- Base.class_eval { include Testing }
+ @controller.class.class_eval { include Testing }
@controller.process_with_new_base_test(@request, @response)
+ @assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {}
@request.session.delete('flash') if @request.session['flash'].blank?
@response
end
@@ -448,7 +449,7 @@ module ActionController
def build_request_uri(action, parameters)
unless @request.env["PATH_INFO"]
- options = @controller.__send__(:url_options).merge(parameters)
+ options = @controller.respond_to?(:url_options) ? @controller.__send__(:url_options).merge(parameters) : parameters
options.update(
:only_path => true,
:action => action,
diff --git a/actionpack/lib/action_dispatch/routing/route.rb b/actionpack/lib/action_dispatch/routing/route.rb
index f91a48e16c..08a8408f25 100644
--- a/actionpack/lib/action_dispatch/routing/route.rb
+++ b/actionpack/lib/action_dispatch/routing/route.rb
@@ -30,7 +30,8 @@ module ActionDispatch
if method = conditions[:request_method]
case method
when Regexp
- method.source.upcase
+ source = method.source.upcase
+ source =~ /\A\^[-A-Z|]+\$\Z/ ? source[1..-2] : source
else
method.to_s.upcase
end
diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb
index c56ebc6438..16f3674164 100644
--- a/actionpack/lib/action_dispatch/testing/test_process.rb
+++ b/actionpack/lib/action_dispatch/testing/test_process.rb
@@ -22,7 +22,7 @@ module ActionDispatch
end
def cookies
- @request.cookies.merge(@response.cookies)
+ HashWithIndifferentAccess.new(@request.cookies.merge(@response.cookies))
end
def redirect_to_url
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index a728fde748..db5f5f301a 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -878,7 +878,7 @@ module ActionView
end
def join_asset_file_contents(paths)
- paths.collect { |path| File.read(asset_file_path!(path)) }.join("\n\n")
+ paths.collect { |path| File.read(asset_file_path!(path, true)) }.join("\n\n")
end
def write_asset_file_contents(joined_asset_path, asset_paths)
@@ -896,8 +896,10 @@ module ActionView
File.join(config.assets_dir, path.split('?').first)
end
- def asset_file_path!(path)
- unless is_uri?(path)
+ def asset_file_path!(path, error_if_file_is_uri = false)
+ if is_uri?(path)
+ raise(Errno::ENOENT, "Asset file #{path} is uri and cannot be merged into single file") if error_if_file_is_uri
+ else
absolute_path = asset_file_path(path)
raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path)
return absolute_path
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index 0401e6a09b..c88bd1efd5 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/string/output_safety'
module ActionView
# = Action View Capture Helper
@@ -38,7 +39,7 @@ module ActionView
value = nil
buffer = with_output_buffer { value = yield(*args) }
if string = buffer.presence || value and string.is_a?(String)
- string
+ ERB::Util.html_escape string
end
end
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index c1214bc44e..875ec9b77b 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -882,6 +882,8 @@ module ActionView
# Returns the separator for a given datetime component
def separator(type)
case type
+ when :year
+ @options[:discard_year] ? "" : @options[:date_separator]
when :month
@options[:discard_month] ? "" : @options[:date_separator]
when :day
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index d6e175c7e8..0470b051c6 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -294,10 +294,9 @@ module ActionView
#
# If you don't need to attach a form to a model instance, then check out
# FormTagHelper#form_tag.
- def form_for(record, options = nil, &proc)
+ def form_for(record, options = {}, &proc)
raise ArgumentError, "Missing block" unless block_given?
- options ||= {}
options[:html] ||= {}
case record
@@ -1278,11 +1277,11 @@ module ActionView
if association.respond_to?(:persisted?)
association = [association] if @object.send(association_name).is_a?(Array)
- elsif !association.is_a?(Array)
+ elsif !association.respond_to?(:to_ary)
association = @object.send(association_name)
end
- if association.is_a?(Array)
+ if association.respond_to?(:to_ary)
explicit_child_index = options[:child_index]
output = ActiveSupport::SafeBuffer.new
association.each do |child|
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index 1488e72c6e..a9400c347f 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -15,7 +15,7 @@ module ActionView
# unchanged if can't be converted into a valid number.
module NumberHelper
- DEFAULT_CURRENCY_VALUES = { :format => "%u%n", :unit => "$", :separator => ".", :delimiter => ",",
+ DEFAULT_CURRENCY_VALUES = { :format => "%u%n", :negative_format => "-%u%n", :unit => "$", :separator => ".", :delimiter => ",",
:precision => 2, :significant => false, :strip_insignificant_zeros => false }
# Raised when argument +number+ param given to the helpers is invalid and
@@ -81,15 +81,18 @@ module ActionView
# in the +options+ hash.
#
# ==== Options
- # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
- # * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
- # * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
- # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
- # * <tt>:format</tt> - Sets the format of the output string (defaults to "%u%n"). The field types are:
- #
- # %u The currency unit
- # %n The number
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
+ # * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
+ # * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
+ # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
+ # * <tt>:format</tt> - Sets the format for non-negative numbers (defaults to "%u%n").
+ # Fields are <tt>%u</tt> for the currency, and <tt>%n</tt>
+ # for the number.
+ # * <tt>:negative_format</tt> - Sets the format for negative numbers (defaults to prepending
+ # an hyphen to the formatted number given by <tt>:format</tt>).
+ # Accepts the same fields than <tt>:format</tt>, except
+ # <tt>%n</tt> is here the absolute value of the number.
#
# ==== Examples
# number_to_currency(1234567890.50) # => $1,234,567,890.50
@@ -97,6 +100,8 @@ module ActionView
# number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506
# number_to_currency(1234567890.506, :locale => :fr) # => 1 234 567 890,506 €
#
+ # number_to_currency(1234567890.50, :negative_format => "(%u%n)")
+ # # => ($1,234,567,890.51)
# number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "")
# # => &pound;1234567890,50
# number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "", :format => "%n %u")
@@ -110,11 +115,17 @@ module ActionView
currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency)
+ defaults[:negative_format] = "-" + options[:format] if options[:format]
options = defaults.merge!(options)
unit = options.delete(:unit)
format = options.delete(:format)
+ if number.to_f < 0
+ format = options.delete(:negative_format)
+ number = number.respond_to?("abs") ? number.abs : number.sub(/^-/, '')
+ end
+
begin
value = number_with_precision(number, options.merge(:raise => true))
format.gsub(/%n/, value).gsub(/%u/, unit).html_safe
diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index b827610456..0803114f44 100644
--- a/actionpack/lib/action_view/template/handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
@@ -15,6 +15,7 @@ module ActionView
super(value.to_s)
end
alias :append= :<<
+ alias :safe_append= :safe_concat
end
class Template
@@ -40,7 +41,11 @@ module ActionView
end
def add_expr_escaped(src, code)
- src << '@output_buffer.append= ' << escaped_expr(code) << ';'
+ if code =~ BLOCK_EXPR
+ src << "@output_buffer.safe_append= " << code
+ else
+ src << "@output_buffer.safe_concat((" << code << ").to_s);"
+ end
end
def add_postamble(src)
diff --git a/actionpack/test/activerecord/active_record_store_test.rb b/actionpack/test/activerecord/active_record_store_test.rb
index f5811a1530..7c595d1b89 100644
--- a/actionpack/test/activerecord/active_record_store_test.rb
+++ b/actionpack/test/activerecord/active_record_store_test.rb
@@ -27,6 +27,12 @@ class ActiveRecordStoreTest < ActionDispatch::IntegrationTest
head :ok
end
+ def renew
+ env["rack.session.options"][:renew] = true
+ session[:foo] = "baz"
+ head :ok
+ end
+
def rescue_action(e) raise end
end
@@ -64,6 +70,20 @@ class ActiveRecordStoreTest < ActionDispatch::IntegrationTest
end
end
end
+
+ define_method("test_renewing_with_#{class_name}_store") do
+ with_store class_name do
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ assert cookies['_session_id']
+
+ get '/renew'
+ assert_response :success
+ assert_not_equal [], headers['Set-Cookie']
+ end
+ end
+ end
end
def test_getting_nil_session_value
diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb
index 3a8a37d967..68febf425d 100644
--- a/actionpack/test/controller/filters_test.rb
+++ b/actionpack/test/controller/filters_test.rb
@@ -78,7 +78,8 @@ class FilterTest < ActionController::TestCase
end
class RenderingController < ActionController::Base
- before_filter :render_something_else
+ before_filter :before_filter_rendering
+ after_filter :unreached_after_filter
def show
@ran_action = true
@@ -86,9 +87,59 @@ class FilterTest < ActionController::TestCase
end
private
- def render_something_else
+ def before_filter_rendering
+ @ran_filter ||= []
+ @ran_filter << "before_filter_rendering"
render :inline => "something else"
end
+
+ def unreached_after_filter
+ @ran_filter << "unreached_after_filter_after_render"
+ end
+ end
+
+ class RenderingForPrependAfterFilterController < RenderingController
+ prepend_after_filter :unreached_prepend_after_filter
+
+ private
+ def unreached_prepend_after_filter
+ @ran_filter << "unreached_preprend_after_filter_after_render"
+ end
+ end
+
+ class BeforeFilterRedirectionController < ActionController::Base
+ before_filter :before_filter_redirects
+ after_filter :unreached_after_filter
+
+ def show
+ @ran_action = true
+ render :inline => "ran show action"
+ end
+
+ def target_of_redirection
+ @ran_target_of_redirection = true
+ render :inline => "ran target_of_redirection action"
+ end
+
+ private
+ def before_filter_redirects
+ @ran_filter ||= []
+ @ran_filter << "before_filter_redirects"
+ redirect_to(:action => 'target_of_redirection')
+ end
+
+ def unreached_after_filter
+ @ran_filter << "unreached_after_filter_after_redirection"
+ end
+ end
+
+ class BeforeFilterRedirectionForPrependAfterFilterController < BeforeFilterRedirectionController
+ prepend_after_filter :unreached_prepend_after_filter_after_redirection
+
+ private
+ def unreached_prepend_after_filter_after_redirection
+ @ran_filter << "unreached_prepend_after_filter_after_redirection"
+ end
end
class ConditionalFilterController < ActionController::Base
@@ -625,6 +676,32 @@ class FilterTest < ActionController::TestCase
assert !assigns["ran_action"]
end
+ def test_before_filter_rendering_breaks_filtering_chain_for_after_filter
+ response = test_process(RenderingController)
+ assert_equal %w( before_filter_rendering ), assigns["ran_filter"]
+ assert !assigns["ran_action"]
+ end
+
+ def test_before_filter_redirects_breaks_filtering_chain_for_after_filter
+ response = test_process(BeforeFilterRedirectionController)
+ assert_response :redirect
+ assert_equal "http://test.host/filter_test/before_filter_redirection/target_of_redirection", redirect_to_url
+ assert_equal %w( before_filter_redirects ), assigns["ran_filter"]
+ end
+
+ def test_before_filter_rendering_breaks_filtering_chain_for_preprend_after_filter
+ response = test_process(RenderingForPrependAfterFilterController)
+ assert_equal %w( before_filter_rendering ), assigns["ran_filter"]
+ assert !assigns["ran_action"]
+ end
+
+ def test_before_filter_redirects_breaks_filtering_chain_for_preprend_after_filter
+ response = test_process(BeforeFilterRedirectionForPrependAfterFilterController)
+ assert_response :redirect
+ assert_equal "http://test.host/filter_test/before_filter_redirection_for_prepend_after_filter/target_of_redirection", redirect_to_url
+ assert_equal %w( before_filter_redirects ), assigns["ran_filter"]
+ end
+
def test_filters_with_mixed_specialization_run_in_order
assert_nothing_raised do
response = test_process(MixedSpecializationController, 'bar')
diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb
index a898ef76e5..b6ce9f7d34 100644
--- a/actionpack/test/controller/mime_responds_test.rb
+++ b/actionpack/test/controller/mime_responds_test.rb
@@ -487,6 +487,10 @@ class RespondWithController < ActionController::Base
respond_with(resource)
end
+ def using_hash_resource
+ respond_with({:result => resource})
+ end
+
def using_resource_with_block
respond_with(resource) do |format|
format.csv { render :text => "CSV" }
@@ -587,6 +591,18 @@ class RespondWithControllerTest < ActionController::TestCase
end
end
+ def test_using_hash_resource
+ @request.accept = "application/xml"
+ get :using_hash_resource
+ assert_equal "application/xml", @response.content_type
+ assert_equal "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n <name>david</name>\n</hash>\n", @response.body
+
+ @request.accept = "application/json"
+ get :using_hash_resource
+ assert_equal "application/json", @response.content_type
+ assert_equal %Q[{"result":["david",13]}], @response.body
+ end
+
def test_using_resource_with_block
@request.accept = "*/*"
get :using_resource_with_block
diff --git a/actionpack/test/controller/new_base/bare_metal_test.rb b/actionpack/test/controller/new_base/bare_metal_test.rb
index 44922cecff..543c02b2c5 100644
--- a/actionpack/test/controller/new_base/bare_metal_test.rb
+++ b/actionpack/test/controller/new_base/bare_metal_test.rb
@@ -39,4 +39,11 @@ module BareMetalTest
assert_equal 404, status
end
end
+
+ class BareControllerTest < ActionController::TestCase
+ test "GET index" do
+ get :index
+ assert_equal "Hello world", @response.body
+ end
+ end
end
diff --git a/actionpack/test/controller/new_base/render_template_test.rb b/actionpack/test/controller/new_base/render_template_test.rb
index d31193a063..9899036fe8 100644
--- a/actionpack/test/controller/new_base/render_template_test.rb
+++ b/actionpack/test/controller/new_base/render_template_test.rb
@@ -9,6 +9,7 @@ module RenderTemplate
"locals.html.erb" => "The secret is <%= secret %>",
"xml_template.xml.builder" => "xml.html do\n xml.p 'Hello'\nend",
"with_raw.html.erb" => "Hello <%=raw '<strong>this is raw</strong>' %>",
+ "with_implicit_raw.html.erb"=> "Hello <%== '<strong>this is also raw</strong>' %>",
"test/with_json.html.erb" => "<%= render :template => 'test/with_json.json' %>",
"test/with_json.json.erb" => "<%= render :template => 'test/final' %>",
"test/final.json.erb" => "{ final: json }",
@@ -51,6 +52,10 @@ module RenderTemplate
render :template => "with_raw"
end
+ def with_implicit_raw
+ render :template => "with_implicit_raw"
+ end
+
def with_error
render :template => "test/with_error"
end
@@ -99,6 +104,11 @@ module RenderTemplate
assert_body "Hello <strong>this is raw</strong>"
assert_status 200
+
+ get :with_implicit_raw
+
+ assert_body "Hello <strong>this is also raw</strong>"
+ assert_status 200
end
test "rendering a template with renders another template with other format that renders other template in the same format" do
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index faeae91f6b..5ec7f12cc1 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -94,6 +94,16 @@ class CookiesTest < ActionController::TestCase
cookies.delete(:user_name, :domain => :all)
head :ok
end
+
+ def symbol_key
+ cookies[:user_name] = "david"
+ head :ok
+ end
+
+ def string_key
+ cookies['user_name'] = "david"
+ head :ok
+ end
end
tests TestController
@@ -291,6 +301,14 @@ class CookiesTest < ActionController::TestCase
assert_cookie_header "user_name=; domain=.nextangle.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
end
+ def test_cookies_hash_is_indifferent_access
+ [:symbol_key, :string_key].each do |cookie_key|
+ get cookie_key
+ assert_equal "david", cookies[:user_name]
+ assert_equal "david", cookies['user_name']
+ end
+ end
+
private
def assert_cookie_header(expected)
header = @response.headers["Set-Cookie"]
diff --git a/actionpack/test/fixtures/layouts/_partial_and_yield.erb b/actionpack/test/fixtures/layouts/_partial_and_yield.erb
new file mode 100644
index 0000000000..74cc428ffa
--- /dev/null
+++ b/actionpack/test/fixtures/layouts/_partial_and_yield.erb
@@ -0,0 +1,2 @@
+<%= render :partial => 'test/partial' %>
+<%= yield %>
diff --git a/actionpack/test/fixtures/layouts/_yield_only.erb b/actionpack/test/fixtures/layouts/_yield_only.erb
new file mode 100644
index 0000000000..37f0bddbd7
--- /dev/null
+++ b/actionpack/test/fixtures/layouts/_yield_only.erb
@@ -0,0 +1 @@
+<%= yield %>
diff --git a/actionpack/test/fixtures/layouts/_yield_with_params.erb b/actionpack/test/fixtures/layouts/_yield_with_params.erb
new file mode 100644
index 0000000000..68e6557fb8
--- /dev/null
+++ b/actionpack/test/fixtures/layouts/_yield_with_params.erb
@@ -0,0 +1 @@
+<%= yield 'Yield!' %>
diff --git a/actionpack/test/fixtures/layouts/yield_with_render_partial_inside.erb b/actionpack/test/fixtures/layouts/yield_with_render_partial_inside.erb
new file mode 100644
index 0000000000..74cc428ffa
--- /dev/null
+++ b/actionpack/test/fixtures/layouts/yield_with_render_partial_inside.erb
@@ -0,0 +1,2 @@
+<%= render :partial => 'test/partial' %>
+<%= yield %>
diff --git a/actionpack/test/fixtures/test/_partial_with_partial.erb b/actionpack/test/fixtures/test/_partial_with_partial.erb
new file mode 100644
index 0000000000..ee0d5037b6
--- /dev/null
+++ b/actionpack/test/fixtures/test/_partial_with_partial.erb
@@ -0,0 +1,2 @@
+<%= render 'test/partial' %>
+partial with partial
diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb
index dba632e6df..ae0c38184d 100644
--- a/actionpack/test/lib/controller/fake_models.rb
+++ b/actionpack/test/lib/controller/fake_models.rb
@@ -184,3 +184,13 @@ module Blog
end
end
end
+
+class ArelLike
+ def to_ary
+ true
+ end
+ def each
+ a = Array.new(2) { |id| Comment.new(id + 1) }
+ a.each { |i| yield i }
+ end
+end
diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb
index 3abcdfbc1e..caf1c694c8 100644
--- a/actionpack/test/template/asset_tag_helper_test.rb
+++ b/actionpack/test/template/asset_tag_helper_test.rb
@@ -727,6 +727,17 @@ class AssetTagHelperTest < ActionView::TestCase
assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js'))
end
+ def test_caching_javascript_include_tag_when_caching_on_and_javascript_file_is_uri
+ ENV["RAILS_ASSET_ID"] = ""
+ config.perform_caching = true
+
+ assert_raise(Errno::ENOENT) {
+ javascript_include_tag('bank', 'robber', 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.js', :cache => true)
+ }
+
+ assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js'))
+ end
+
def test_caching_javascript_include_tag_when_caching_off_and_missing_javascript_file
ENV["RAILS_ASSET_ID"] = ""
config.perform_caching = false
diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb
index 8f81076299..03050485fa 100644
--- a/actionpack/test/template/capture_helper_test.rb
+++ b/actionpack/test/template/capture_helper_test.rb
@@ -28,6 +28,16 @@ class CaptureHelperTest < ActionView::TestCase
assert_nil @av.capture { 1 }
end
+ def test_capture_escapes_html
+ string = @av.capture { '<em>bar</em>' }
+ assert_equal '&lt;em&gt;bar&lt;/em&gt;', string
+ end
+
+ def test_capture_doesnt_escape_twice
+ string = @av.capture { '&lt;em&gt;bar&lt;/em&gt;'.html_safe }
+ assert_equal '&lt;em&gt;bar&lt;/em&gt;', string
+ end
+
def test_content_for
assert ! content_for?(:title)
content_for :title, 'title'
diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb
index 0cf7885772..55c384e68f 100644
--- a/actionpack/test/template/date_helper_test.rb
+++ b/actionpack/test/template/date_helper_test.rb
@@ -1584,6 +1584,47 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, date_select("post", "written_on", { :date_separator => " / " })
end
+ def test_date_select_with_separator_and_order
+ @post = Post.new
+ @post.written_on = Date.new(2004, 6, 15)
+
+ expected = %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n}
+ expected << %{<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15" selected="selected">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n}
+ expected << "</select>\n"
+
+ expected << " / "
+
+ expected << %{<select id="post_written_on_2i" name="post[written_on(2i)]">\n}
+ expected << %{<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n}
+ expected << "</select>\n"
+
+ expected << " / "
+
+ expected << %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}
+ expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n}
+ expected << "</select>\n"
+
+ assert_dom_equal expected, date_select("post", "written_on", { :order => [:day, :month, :year], :date_separator => " / " })
+ end
+
+ def test_date_select_with_separator_and_order_and_year_discarded
+ @post = Post.new
+ @post.written_on = Date.new(2004, 6, 15)
+
+ expected = %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n}
+ expected << %{<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15" selected="selected">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n}
+ expected << "</select>\n"
+
+ expected << " / "
+
+ expected << %{<select id="post_written_on_2i" name="post[written_on(2i)]">\n}
+ expected << %{<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n}
+ expected << "</select>\n"
+ expected << %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}
+
+ assert_dom_equal expected, date_select("post", "written_on", { :order => [:day, :month, :year], :discard_year => true, :date_separator => " / " })
+ end
+
def test_date_select_with_default_prompt
@post = Post.new
@post.written_on = Date.new(2004, 6, 15)
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index acb6e7aa64..2c60096475 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -1230,6 +1230,27 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_nested_fields_for_arel_like
+ @post.comments = ArelLike.new
+
+ form_for(@post) do |f|
+ concat f.text_field(:title)
+ concat f.fields_for(:comments, @post.comments) { |cf|
+ concat cf.text_field(:name)
+ }
+ end
+
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') 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 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_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection_different_from_record_one
comments = Array.new(2) { |id| Comment.new(id + 1) }
@post.comments = []
diff --git a/actionpack/test/template/number_helper_i18n_test.rb b/actionpack/test/template/number_helper_i18n_test.rb
index c82ead663f..5df09b4d3b 100644
--- a/actionpack/test/template/number_helper_i18n_test.rb
+++ b/actionpack/test/template/number_helper_i18n_test.rb
@@ -7,7 +7,7 @@ class NumberHelperTest < ActionView::TestCase
I18n.backend.store_translations 'ts',
:number => {
:format => { :precision => 3, :delimiter => ',', :separator => '.', :significant => false, :strip_insignificant_zeros => false },
- :currency => { :format => { :unit => '&$', :format => '%u - %n', :precision => 2 } },
+ :currency => { :format => { :unit => '&$', :format => '%u - %n', :negative_format => '(%u - %n)', :precision => 2 } },
:human => {
:format => {
:precision => 2,
@@ -43,11 +43,14 @@ class NumberHelperTest < ActionView::TestCase
def test_number_to_i18n_currency
assert_equal("&$ - 10.00", number_to_currency(10, :locale => 'ts'))
+ assert_equal("(&$ - 10.00)", number_to_currency(-10, :locale => 'ts'))
+ assert_equal("-10.00 - &$", number_to_currency(-10, :locale => 'ts', :format => "%n - %u"))
end
def test_number_to_currency_with_clean_i18n_settings
clean_i18n do
assert_equal("$10.00", number_to_currency(10))
+ assert_equal("-$10.00", number_to_currency(-10))
end
end
diff --git a/actionpack/test/template/number_helper_test.rb b/actionpack/test/template/number_helper_test.rb
index dcdf28ddd5..ab127521ad 100644
--- a/actionpack/test/template/number_helper_test.rb
+++ b/actionpack/test/template/number_helper_test.rb
@@ -45,11 +45,15 @@ class NumberHelperTest < ActionView::TestCase
def test_number_to_currency
assert_equal("$1,234,567,890.50", number_to_currency(1234567890.50))
assert_equal("$1,234,567,890.51", number_to_currency(1234567890.506))
+ assert_equal("-$1,234,567,890.50", number_to_currency(-1234567890.50))
+ assert_equal("-$ 1,234,567,890.50", number_to_currency(-1234567890.50, {:format => "%u %n"}))
+ assert_equal("($1,234,567,890.50)", number_to_currency(-1234567890.50, {:negative_format => "(%u%n)"}))
assert_equal("$1,234,567,892", number_to_currency(1234567891.50, {:precision => 0}))
assert_equal("$1,234,567,890.5", number_to_currency(1234567890.50, {:precision => 1}))
assert_equal("&pound;1234567890,50", number_to_currency(1234567890.50, {:unit => "&pound;", :separator => ",", :delimiter => ""}))
assert_equal("$1,234,567,890.50", number_to_currency("1234567890.50"))
assert_equal("1,234,567,890.50 K&#269;", number_to_currency("1234567890.50", {:unit => "K&#269;", :format => "%n %u"}))
+ assert_equal("1,234,567,890.50 - K&#269;", number_to_currency("-1234567890.50", {:unit => "K&#269;", :format => "%n %u", :negative_format => "%n - %u"}))
end
def test_number_to_percentage
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index 17bb610b6a..08d50257d4 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -247,6 +247,36 @@ module RenderTestCases
@view.render(:file => "test/hello_world.erb", :layout => "layouts/yield_with_render_inline_inside")
end
+ def test_render_with_layout_which_renders_another_partial
+ assert_equal %(partial html\nHello world!\n),
+ @view.render(:file => "test/hello_world.erb", :layout => "layouts/yield_with_render_partial_inside")
+ end
+
+ def test_render_layout_with_block_and_yield
+ assert_equal %(Content from block!\n),
+ @view.render(:layout => "layouts/yield_only") { "Content from block!" }
+ end
+
+ def test_render_layout_with_block_and_yield_with_params
+ assert_equal %(Yield! Content from block!\n),
+ @view.render(:layout => "layouts/yield_with_params") { |param| "#{param} Content from block!" }
+ end
+
+ def test_render_layout_with_block_which_renders_another_partial_and_yields
+ assert_equal %(partial html\nContent from block!\n),
+ @view.render(:layout => "layouts/partial_and_yield") { "Content from block!" }
+ end
+
+ def test_render_partial_and_layout_without_block_with_locals
+ assert_equal %(Before (Foo!)\npartial html\nAfter),
+ @view.render(:partial => 'test/partial', :layout => 'test/layout_for_partial', :locals => { :name => 'Foo!'})
+ end
+
+ def test_render_partial_and_layout_without_block_with_locals_and_rendering_another_partial
+ assert_equal %(Before (Foo!)\npartial html\npartial with partial\n\nAfter),
+ @view.render(:partial => 'test/partial_with_partial', :layout => 'test/layout_for_partial', :locals => { :name => 'Foo!'})
+ end
+
def test_render_with_nested_layout
assert_equal %(<title>title</title>\n\n<div id="column">column</div>\n<div id="content">content</div>\n),
@view.render(:file => "test/nested_layout.erb", :layout => "layouts/yield")
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index bc2548e06c..4a8cea36d4 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -263,12 +263,7 @@ class UrlHelperTest < ActiveSupport::TestCase
assert_equal "<strong>Showing</strong>",
link_to_unless(true, "Showing", url_hash) { |name|
- "<strong>#{name}</strong>"
- }
-
- assert_equal "<strong>Showing</strong>",
- link_to_unless(true, "Showing", url_hash) { |name|
- "<strong>#{name}</strong>"
+ "<strong>#{name}</strong>".html_safe
}
assert_equal "test",
diff --git a/activemodel/CHANGELOG b/activemodel/CHANGELOG
index e93d84ab59..4e963c77b0 100644
--- a/activemodel/CHANGELOG
+++ b/activemodel/CHANGELOG
@@ -2,6 +2,10 @@
* No changes
+*Rails 3.0.2 (unreleased)*
+
+* No changes
+
*Rails 3.0.1 (October 15, 2010)*
* No Changes, just a version bump.
diff --git a/activemodel/test/cases/serializeration/xml_serialization_test.rb b/activemodel/test/cases/serializeration/xml_serialization_test.rb
index ff786658b7..cc19d322b3 100644
--- a/activemodel/test/cases/serializeration/xml_serialization_test.rb
+++ b/activemodel/test/cases/serializeration/xml_serialization_test.rb
@@ -70,6 +70,13 @@ class XmlSerializationTest < ActiveModel::TestCase
assert_match %r{<CreatedAt}, @xml
end
+ test "should allow lower-camelized tags" do
+ @xml = @contact.to_xml :root => 'xml_contact', :camelize => :lower
+ assert_match %r{^<xmlContact>}, @xml
+ assert_match %r{</xmlContact>$}, @xml
+ assert_match %r{<createdAt}, @xml
+ end
+
test "should allow skipped types" do
@xml = @contact.to_xml :skip_types => true
assert_match %r{<age>25</age>}, @xml
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index d3530e0da9..11eb47917d 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -18,6 +18,35 @@
[Aaron Patterson]
+*Rails 3.0.2 (unreleased)*
+
+* reorder is deprecated in favor of except(:order).order(...) [Santiago Pastorino]
+
+* except is now AR public API
+
+ Model.order('name').except(:order).order('salary')
+
+ generates:
+
+ SELECT * FROM models ORDER BY salary
+
+ [Santiago Pastorino]
+
+* The following code:
+
+ Model.limit(10).scoping { Model.count }
+
+ now generates the following SQL:
+
+ SELECT COUNT(*) FROM models LIMIT 10
+
+ This may not return what you want. Instead, you may with to do something
+ like this:
+
+ Model.limit(10).scoping { Model.all.size }
+
+ [Aaron Patterson]
+
*Rails 3.0.1 (October 15, 2010)*
* Introduce a fix for CVE-2010-3993
diff --git a/activerecord/activerecord.gemspec b/activerecord/activerecord.gemspec
index b8a980b1fb..b1df24844a 100644
--- a/activerecord/activerecord.gemspec
+++ b/activerecord/activerecord.gemspec
@@ -23,6 +23,6 @@ Gem::Specification.new do |s|
s.add_dependency('activesupport', version)
s.add_dependency('activemodel', version)
- s.add_dependency('arel', '~> 2.0.0')
+ s.add_dependency('arel', '~> 2.0.2')
s.add_dependency('tzinfo', '~> 0.3.23')
end
diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb
index 16206c1056..8cd7389005 100644
--- a/activerecord/lib/active_record/aggregations.rb
+++ b/activerecord/lib/active_record/aggregations.rb
@@ -6,7 +6,7 @@ module ActiveRecord
def clear_aggregation_cache #:nodoc:
self.class.reflect_on_all_aggregations.to_a.each do |assoc|
instance_variable_set "@#{assoc.name}", nil
- end unless self.new_record?
+ end if self.persisted?
end
# Active Record implements aggregation through a macro-like class method called +composed_of+
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index dc466eafc2..08a4ebfd7e 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -118,7 +118,7 @@ module ActiveRecord
def clear_association_cache #:nodoc:
self.class.reflect_on_all_associations.to_a.each do |assoc|
instance_variable_set "@#{assoc.name}", nil
- end unless self.new_record?
+ end if self.persisted?
end
private
@@ -1839,8 +1839,6 @@ module ActiveRecord
@join_parts = [JoinBase.new(base, joins)]
@associations = {}
@reflections = []
- @base_records_hash = {}
- @base_records_in_order = []
@table_aliases = Hash.new(0)
@table_aliases[base.table_name] = 1
build(associations)
@@ -1874,15 +1872,18 @@ module ActiveRecord
end
def instantiate(rows)
- rows.each_with_index do |row, i|
- primary_id = join_base.record_id(row)
- unless @base_records_hash[primary_id]
- @base_records_in_order << (@base_records_hash[primary_id] = join_base.instantiate(row))
- end
- construct(@base_records_hash[primary_id], @associations, join_associations.dup, row)
- end
- remove_duplicate_results!(join_base.active_record, @base_records_in_order, @associations)
- return @base_records_in_order
+ primary_key = join_base.aliased_primary_key
+ parents = {}
+
+ records = rows.map { |model|
+ primary_id = model[primary_key]
+ parent = parents[primary_id] ||= join_base.instantiate(model)
+ construct(parent, @associations, join_associations.dup, model)
+ parent
+ }.uniq
+
+ remove_duplicate_results!(join_base.active_record, records, @associations)
+ records
end
def remove_duplicate_results!(base, records, associations)
@@ -1982,10 +1983,13 @@ module ActiveRecord
def construct(parent, associations, join_parts, row)
case associations
when Symbol, String
+ name = associations.to_s
+
join_part = join_parts.detect { |j|
- j.reflection.name.to_s == associations.to_s &&
+ j.reflection.name.to_s == name &&
j.parent_table_name == parent.class.table_name }
- raise(ConfigurationError, "No such association") if join_part.nil?
+
+ raise(ConfigurationError, "No such association") unless join_part
join_parts.delete(join_part)
construct_association(parent, join_part, row)
@@ -1995,13 +1999,7 @@ module ActiveRecord
end
when Hash
associations.sort_by { |k,_| k.to_s }.each do |name, assoc|
- join_part = join_parts.detect{ |j|
- j.reflection.name.to_s == name.to_s &&
- j.parent_table_name == parent.class.table_name }
- raise(ConfigurationError, "No such association") if join_part.nil?
-
- association = construct_association(parent, join_part, row)
- join_parts.delete(join_part)
+ association = construct(parent, name, join_parts, row)
construct(association, assoc, join_parts, row) if association
end
else
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index 896e18af01..71d8c2d3c8 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -120,13 +120,13 @@ module ActiveRecord
# Since << flattens its argument list and inserts each record, +push+ and +concat+ behave identically.
def <<(*records)
result = true
- load_target if @owner.new_record?
+ load_target unless @owner.persisted?
transaction do
flatten_deeper(records).each do |record|
raise_on_type_mismatch(record)
add_record_to_target_with_callbacks(record) do |r|
- result &&= insert_record(record) unless @owner.new_record?
+ result &&= insert_record(record) if @owner.persisted?
end
end
end
@@ -285,12 +285,12 @@ module ActiveRecord
# This method is abstract in the sense that it relies on
# +count_records+, which is a method descendants have to provide.
def size
- if @owner.new_record? || (loaded? && !@reflection.options[:uniq])
+ if !@owner.persisted? || (loaded? && !@reflection.options[:uniq])
@target.size
elsif !loaded? && @reflection.options[:group]
load_target.size
elsif !loaded? && !@reflection.options[:uniq] && @target.is_a?(Array)
- unsaved_records = @target.select { |r| r.new_record? }
+ unsaved_records = @target.reject { |r| r.persisted? }
unsaved_records.size + count_records
else
count_records
@@ -357,7 +357,7 @@ module ActiveRecord
def include?(record)
return false unless record.is_a?(@reflection.klass)
- return include_in_memory?(record) if record.new_record?
+ return include_in_memory?(record) unless record.persisted?
load_target if @reflection.options[:finder_sql] && !loaded?
return @target.include?(record) if loaded?
exists?(record)
@@ -372,7 +372,7 @@ module ActiveRecord
end
def load_target
- if !@owner.new_record? || foreign_key_present
+ if @owner.persisted? || foreign_key_present
begin
if !loaded?
if @target.is_a?(Array) && @target.any?
@@ -513,7 +513,7 @@ module ActiveRecord
transaction do
records.each { |record| callback(:before_remove, record) }
- old_records = records.reject { |r| r.new_record? }
+ old_records = records.select { |r| r.persisted? }
yield(records, old_records)
records.each { |record| callback(:after_remove, record) }
end
@@ -538,14 +538,14 @@ module ActiveRecord
end
def ensure_owner_is_not_new
- if @owner.new_record?
+ unless @owner.persisted?
raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved"
end
end
def fetch_first_or_last_using_find?(args)
- args.first.kind_of?(Hash) || !(loaded? || @owner.new_record? || @reflection.options[:finder_sql] ||
- @target.any? { |record| record.new_record? } || args.first.kind_of?(Integer))
+ args.first.kind_of?(Hash) || !(loaded? || !@owner.persisted? || @reflection.options[:finder_sql] ||
+ !@target.all? { |record| record.persisted? } || args.first.kind_of?(Integer))
end
def include_in_memory?(record)
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index 0c12c3737d..09bba213ce 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -53,7 +53,7 @@ module ActiveRecord
alias_method :proxy_respond_to?, :respond_to?
alias_method :proxy_extend, :extend
delegate :to_param, :to => :proxy_target
- instance_methods.each { |m| undef_method m unless m.to_s =~ /^(?:nil\?|send|object_id|to_a)$|^__|proxy_/ }
+ instance_methods.each { |m| undef_method m unless m.to_s =~ /^(?:nil\?|send|object_id|to_a)$|^__|^respond_to_missing|proxy_/ }
def initialize(owner, reflection)
@owner, @reflection = owner, reflection
@@ -175,10 +175,10 @@ module ActiveRecord
# If the association is polymorphic the type of the owner is also set.
def set_belongs_to_association_for(record)
if @reflection.options[:as]
- record["#{@reflection.options[:as]}_id"] = @owner.id unless @owner.new_record?
+ record["#{@reflection.options[:as]}_id"] = @owner.id if @owner.persisted?
record["#{@reflection.options[:as]}_type"] = @owner.class.base_class.name.to_s
else
- unless @owner.new_record?
+ if @owner.persisted?
primary_key = @reflection.options[:primary_key] || :id
record[@reflection.primary_key_name] = @owner.send(primary_key)
end
@@ -252,7 +252,7 @@ module ActiveRecord
def load_target
return nil unless defined?(@loaded)
- if !loaded? and (!@owner.new_record? || foreign_key_present)
+ if !loaded? and (@owner.persisted? || foreign_key_present)
@target = find_target
end
diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb
index 34b6cd5576..b624951cd9 100644
--- a/activerecord/lib/active_record/associations/belongs_to_association.rb
+++ b/activerecord/lib/active_record/associations/belongs_to_association.rb
@@ -14,7 +14,7 @@ module ActiveRecord
counter_cache_name = @reflection.counter_cache_column
if record.nil?
- if counter_cache_name && !@owner.new_record?
+ if counter_cache_name && @owner.persisted?
@reflection.klass.decrement_counter(counter_cache_name, previous_record_id) if @owner[@reflection.primary_key_name]
end
@@ -22,13 +22,13 @@ module ActiveRecord
else
raise_on_type_mismatch(record)
- if counter_cache_name && !@owner.new_record? && record.id != @owner[@reflection.primary_key_name]
+ if counter_cache_name && @owner.persisted? && record.id != @owner[@reflection.primary_key_name]
@reflection.klass.increment_counter(counter_cache_name, record.id)
@reflection.klass.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name]
end
@target = (AssociationProxy === record ? record.target : record)
- @owner[@reflection.primary_key_name] = record_id(record) unless record.new_record?
+ @owner[@reflection.primary_key_name] = record_id(record) if record.persisted?
@updated = true
end
diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
index 1fc9aba5cf..da742fa668 100644
--- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
@@ -34,7 +34,7 @@ module ActiveRecord
end
def insert_record(record, force = true, validate = true)
- if record.new_record?
+ unless record.persisted?
if force
record.save!
else
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index 437c8b1fd6..51770cff0f 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -59,7 +59,7 @@ module ActiveRecord
end
def insert_record(record, force = true, validate = true)
- if record.new_record?
+ unless record.persisted?
if force
record.save!
else
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
index 17901387e9..e6e037441f 100644
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -30,18 +30,18 @@ module ActiveRecord
if dependent? && !dont_save
case @reflection.options[:dependent]
when :delete
- @target.delete unless @target.new_record?
+ @target.delete if @target.persisted?
@owner.clear_association_cache
when :destroy
- @target.destroy unless @target.new_record?
+ @target.destroy if @target.persisted?
@owner.clear_association_cache
when :nullify
@target[@reflection.primary_key_name] = nil
- @target.save unless @owner.new_record? || @target.new_record?
+ @target.save if @owner.persisted? && @target.persisted?
end
else
@target[@reflection.primary_key_name] = nil
- @target.save unless @owner.new_record? || @target.new_record?
+ @target.save if @owner.persisted? && @target.persisted?
end
end
@@ -56,7 +56,7 @@ module ActiveRecord
set_inverse_instance(obj, @owner)
@loaded = true
- unless @owner.new_record? or obj.nil? or dont_save
+ unless !@owner.persisted? or obj.nil? or dont_save
return (obj.save ? self : false)
else
return (obj.nil? ? nil : self)
@@ -113,7 +113,7 @@ module ActiveRecord
if replace_existing
replace(record, true)
else
- record[@reflection.primary_key_name] = @owner.id unless @owner.new_record?
+ record[@reflection.primary_key_name] = @owner.id if @owner.persisted?
self.target = record
set_inverse_instance(record, @owner)
end
diff --git a/activerecord/lib/active_record/associations/has_one_through_association.rb b/activerecord/lib/active_record/associations/has_one_through_association.rb
index 7f28abf464..6e98f7dffb 100644
--- a/activerecord/lib/active_record/associations/has_one_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_through_association.rb
@@ -21,7 +21,7 @@ module ActiveRecord
if current_object
new_value ? current_object.update_attributes(construct_join_attributes(new_value)) : current_object.destroy
elsif new_value
- if @owner.new_record?
+ unless @owner.persisted?
self.target = new_value
through_association = @owner.send(:association_instance_get, @reflection.through_reflection.name)
through_association.build(construct_join_attributes(new_value))
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index 82d94b848a..75ae06f5e9 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -3,10 +3,11 @@ 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?
+ # Returns this record's primary key value wrapped in an Array or nil if
+ # the record is not persisted? or has just been destroyed.
def to_key
- new_record? ? nil : [ id ]
+ key = send(self.class.primary_key)
+ [key] if key
end
module ClassMethods
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index 0b89a49896..cb5bc06580 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -217,7 +217,7 @@ module ActiveRecord
# Returns whether or not this record has been changed in any way (including whether
# any of its nested autosave associations are likewise changed)
def changed_for_autosave?
- new_record? || changed? || marked_for_destruction? || nested_records_changed_for_autosave?
+ !persisted? || changed? || marked_for_destruction? || nested_records_changed_for_autosave?
end
private
@@ -231,7 +231,7 @@ module ActiveRecord
elsif autosave
association.target.find_all { |record| record.changed_for_autosave? }
else
- association.target.find_all { |record| record.new_record? }
+ association.target.find_all { |record| !record.persisted? }
end
end
@@ -257,7 +257,7 @@ module ActiveRecord
# +reflection+.
def validate_collection_association(reflection)
if association = association_instance_get(reflection.name)
- if records = associated_records_to_validate_or_save(association, new_record?, reflection.options[:autosave])
+ if records = associated_records_to_validate_or_save(association, !persisted?, reflection.options[:autosave])
records.each { |record| association_valid?(reflection, record) }
end
end
@@ -286,7 +286,7 @@ module ActiveRecord
# Is used as a before_save callback to check while saving a collection
# association whether or not the parent was a new record before saving.
def before_save_collection_association
- @new_record_before_save = new_record?
+ @new_record_before_save = !persisted?
true
end
@@ -308,7 +308,7 @@ module ActiveRecord
if autosave && record.marked_for_destruction?
association.destroy(record)
- elsif autosave != false && (@new_record_before_save || record.new_record?)
+ elsif autosave != false && (@new_record_before_save || !record.persisted?)
if autosave
saved = association.send(:insert_record, record, false, false)
else
@@ -343,7 +343,7 @@ module ActiveRecord
association.destroy
else
key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
- if autosave != false && (new_record? || association.new_record? || association[reflection.primary_key_name] != key || autosave)
+ if autosave != false && (!persisted? || !association.persisted? || association[reflection.primary_key_name] != key || autosave)
association[reflection.primary_key_name] = key
saved = association.save(:validate => !autosave)
raise ActiveRecord::Rollback if !saved && autosave
@@ -363,7 +363,7 @@ module ActiveRecord
if autosave && association.marked_for_destruction?
association.destroy
elsif autosave != false
- saved = association.save(:validate => !autosave) if association.new_record? || autosave
+ saved = association.save(:validate => !autosave) if !association.persisted? || autosave
if association.updated?
association_id = association.send(reflection.options[:primary_key] || :id)
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 06a388cd21..f588475bbf 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -204,7 +204,7 @@ module ActiveRecord #:nodoc:
#
# # No 'Winter' tag exists
# winter = Tag.find_or_initialize_by_name("Winter")
- # winter.new_record? # true
+ # winter.persisted? # false
#
# To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of
# a list of parameters.
@@ -1368,7 +1368,7 @@ MSG
def initialize(attributes = nil)
@attributes = attributes_from_column_definition
@attributes_cache = {}
- @new_record = true
+ @persisted = false
@readonly = false
@destroyed = false
@marked_for_destruction = false
@@ -1403,7 +1403,7 @@ MSG
clear_aggregation_cache
clear_association_cache
@attributes_cache = {}
- @new_record = true
+ @persisted = false
ensure_proper_type
populate_with_current_scope_attributes
@@ -1422,7 +1422,8 @@ MSG
def init_with(coder)
@attributes = coder['attributes']
@attributes_cache, @previously_changed, @changed_attributes = {}, {}, {}
- @new_record = @readonly = @destroyed = @marked_for_destruction = false
+ @readonly = @destroyed = @marked_for_destruction = false
+ @persisted = true
_run_find_callbacks
_run_initialize_callbacks
end
@@ -1463,7 +1464,7 @@ MSG
# Person.find(5).cache_key # => "people/5-20071224150000" (updated_at available)
def cache_key
case
- when new_record?
+ when !persisted?
"#{self.class.model_name.cache_key}/new"
when timestamp = self[:updated_at]
"#{self.class.model_name.cache_key}/#{id}-#{timestamp.to_s(:number)}"
@@ -1584,8 +1585,9 @@ MSG
# Returns true if the +comparison_object+ is the same object, or is of the same type and has the same id.
def ==(comparison_object)
comparison_object.equal?(self) ||
- (comparison_object.instance_of?(self.class) &&
- comparison_object.id == id && !comparison_object.new_record?)
+ persisted? &&
+ (comparison_object.instance_of?(self.class) &&
+ comparison_object.id == id)
end
# Delegates to ==
@@ -1630,7 +1632,7 @@ MSG
# Returns the contents of the record as a nicely formatted string.
def inspect
attributes_as_nice_string = self.class.column_names.collect { |name|
- if has_attribute?(name) || new_record?
+ if has_attribute?(name) || !persisted?
"#{name}: #{attribute_for_inspect(name)}"
end
}.compact.join(", ")
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 6178130c00..ee9a0af35c 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -50,7 +50,7 @@ module ActiveRecord
# Executes +sql+ statement in the context of this connection using
# +binds+ as the bind substitutes. +name+ is logged along with
# the executed +sql+ statement.
- def exec(sql, name = 'SQL', binds = [])
+ def exec_query(sql, name = 'SQL', binds = [])
end
# Returns the last auto-generated ID from the affected table.
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 7d47d06ae1..ce2352486b 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -326,7 +326,7 @@ module ActiveRecord
@statements.clear
end
- def exec(sql, name = 'SQL', binds = [])
+ def exec_query(sql, name = 'SQL', binds = [])
log(sql, name) do
result = nil
@@ -708,7 +708,7 @@ module ActiveRecord
def select(sql, name = nil, binds = [])
@connection.query_with_result = true
- rows = exec(sql, name, binds).to_a
+ rows = exec_query(sql, name, binds).to_a
@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/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 58c0f85dc2..ccc5085b84 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -398,7 +398,7 @@ module ActiveRecord
# Set the authorized user for this session
def session_auth=(user)
clear_cache!
- exec "SET SESSION AUTHORIZATION #{user}"
+ exec_query "SET SESSION AUTHORIZATION #{user}"
end
# REFERENTIAL INTEGRITY ====================================
@@ -532,7 +532,7 @@ module ActiveRecord
Arel.sql("$#{current_values.length + 1}")
end
- def exec(sql, name = 'SQL', binds = [])
+ def exec_query(sql, name = 'SQL', binds = [])
return exec_no_cache(sql, name) if binds.empty?
log(sql, name) do
@@ -714,8 +714,8 @@ module ActiveRecord
# Returns the list of all column definitions for a table.
def columns(table_name, name = nil)
# Limit, precision, and scale are all handled by the superclass.
- column_definitions(table_name).collect do |name, type, default, notnull|
- PostgreSQLColumn.new(name, default, type, notnull == 'f')
+ column_definitions(table_name).collect do |column_name, type, default, notnull|
+ PostgreSQLColumn.new(column_name, default, type, notnull == 'f')
end
end
@@ -932,12 +932,12 @@ module ActiveRecord
# requires that the ORDER BY include the distinct column.
#
# distinct("posts.id", "posts.created_at desc")
- def distinct(columns, order_by) #:nodoc:
- return "DISTINCT #{columns}" if order_by.blank?
+ def distinct(columns, orders) #:nodoc:
+ return "DISTINCT #{columns}" if orders.empty?
# Construct a clean list of column names from the ORDER BY clause, removing
# any ASC/DESC modifiers
- order_columns = order_by.split(',').collect { |s| s.split.first }
+ order_columns = orders.collect { |s| s =~ /^(.+)\s+(ASC|DESC)\s*$/i ? $1 : s }
order_columns.delete_if { |c| c.blank? }
order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
@@ -1040,7 +1040,7 @@ module ActiveRecord
# Executes a SELECT query and returns the results, performing any data type
# conversions that are required to be performed here instead of in PostgreSQLColumn.
def select(sql, name = nil, binds = [])
- exec(sql, name, binds).to_a
+ exec_query(sql, name, binds).to_a
end
def select_raw(sql, name = nil)
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index fc4d84a4f2..d76fc4103e 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -143,7 +143,7 @@ module ActiveRecord
# DATABASE STATEMENTS ======================================
- def exec(sql, name = nil, binds = [])
+ def exec_query(sql, name = nil, binds = [])
log(sql, name) do
# Don't cache statements without bind values
@@ -186,7 +186,7 @@ module ActiveRecord
alias :create :insert_sql
def select_rows(sql, name = nil)
- exec(sql, name).rows
+ exec_query(sql, name).rows
end
def begin_db_transaction #:nodoc:
@@ -210,7 +210,7 @@ module ActiveRecord
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
SQL
- exec(sql, name).map do |row|
+ exec_query(sql, name).map do |row|
row['name']
end
end
@@ -222,12 +222,12 @@ module ActiveRecord
end
def indexes(table_name, name = nil) #:nodoc:
- exec("PRAGMA index_list(#{quote_table_name(table_name)})", name).map do |row|
+ exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", name).map do |row|
IndexDefinition.new(
table_name,
row['name'],
row['unique'] != 0,
- exec("PRAGMA index_info('#{row['name']}')").map { |col|
+ exec_query("PRAGMA index_info('#{row['name']}')").map { |col|
col['name']
})
end
@@ -241,11 +241,11 @@ module ActiveRecord
end
def remove_index!(table_name, index_name) #:nodoc:
- exec "DROP INDEX #{quote_column_name(index_name)}"
+ exec_query "DROP INDEX #{quote_column_name(index_name)}"
end
def rename_table(name, new_name)
- exec "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
+ exec_query "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
end
# See: http://www.sqlite.org/lang_altertable.html
@@ -282,7 +282,7 @@ module ActiveRecord
def change_column_null(table_name, column_name, null, default = nil)
unless null || default.nil?
- exec("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
+ exec_query("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
end
alter_table(table_name) do |definition|
definition[column_name].null = null
@@ -314,7 +314,7 @@ module ActiveRecord
protected
def select(sql, name = nil, binds = []) #:nodoc:
- result = exec(sql, name, binds)
+ result = exec_query(sql, name, binds)
columns = result.columns.map { |column|
column.sub(/^"?\w+"?\./, '')
}
@@ -399,11 +399,11 @@ module ActiveRecord
quoted_columns = columns.map { |col| quote_column_name(col) } * ','
quoted_to = quote_table_name(to)
- exec("SELECT * FROM #{quote_table_name(from)}").each do |row|
+ exec_query("SELECT * FROM #{quote_table_name(from)}").each do |row|
sql = "INSERT INTO #{quoted_to} (#{quoted_columns}) VALUES ("
sql << columns.map {|col| quote row[column_mappings[col]]} * ', '
sql << ')'
- exec sql
+ exec_query sql
end
end
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index b6f87a57b8..bf626301f1 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -109,7 +109,7 @@ module ActiveRecord
def destroy #:nodoc:
return super unless locking_enabled?
- unless new_record?
+ if persisted?
lock_col = self.class.locking_column
previous_value = send(lock_col).to_i
diff --git a/activerecord/lib/active_record/locking/pessimistic.rb b/activerecord/lib/active_record/locking/pessimistic.rb
index 9ad6a2baf7..d900831e13 100644
--- a/activerecord/lib/active_record/locking/pessimistic.rb
+++ b/activerecord/lib/active_record/locking/pessimistic.rb
@@ -47,7 +47,7 @@ module ActiveRecord
# or pass true for "FOR UPDATE" (the default, an exclusive row lock). Returns
# the locked record.
def lock!(lock = true)
- reload(:lock => lock) unless new_record?
+ reload(:lock => lock) if persisted?
self
end
end
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index aca91c907d..fb48459b6f 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -323,7 +323,7 @@ module ActiveRecord
(options[:update_only] || record.id.to_s == attributes['id'].to_s)
assign_to_or_mark_for_destruction(record, attributes, options[:allow_destroy]) unless call_reject_if(association_name, attributes)
- elsif attributes['id']
+ elsif !attributes['id'].blank?
raise_nested_attributes_record_not_found(association_name, attributes['id'])
elsif !reject_new_record?(association_name, attributes)
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 707c1a05be..594a2214bb 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -4,7 +4,7 @@ module ActiveRecord
# Returns true if this object hasn't been saved yet -- that is, a record
# for the object doesn't exist in the data store yet; otherwise, returns false.
def new_record?
- @new_record
+ !@persisted
end
# Returns true if this object has been destroyed, otherwise returns false.
@@ -15,7 +15,7 @@ module ActiveRecord
# Returns if the record is persisted, i.e. it's not a new record and it was
# not destroyed.
def persisted?
- !(new_record? || destroyed?)
+ @persisted && !destroyed?
end
# Saves the model.
@@ -94,8 +94,9 @@ module ActiveRecord
became = klass.new
became.instance_variable_set("@attributes", @attributes)
became.instance_variable_set("@attributes_cache", @attributes_cache)
- became.instance_variable_set("@new_record", new_record?)
+ became.instance_variable_set("@persisted", persisted?)
became.instance_variable_set("@destroyed", destroyed?)
+ became.type = klass.name unless self.class.descends_from_active_record?
became
end
@@ -240,7 +241,7 @@ module ActiveRecord
private
def create_or_update
raise ReadOnlyRecord if readonly?
- result = new_record? ? create : update
+ result = persisted? ? update : create
result != false
end
@@ -269,7 +270,7 @@ module ActiveRecord
self.id ||= new_id
- @new_record = false
+ @persisted = true
id
end
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index fe1ef2e2e3..e9e9c85122 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -171,14 +171,16 @@ module ActiveRecord
def exists?(id = nil)
id = id.id if ActiveRecord::Base === id
+ relation = select(primary_key).limit(1)
+
case id
when Array, Hash
- where(id).exists?
+ relation = relation.where(id)
else
- relation = select(primary_key).limit(1)
relation = relation.where(primary_key.eq(id)) if id
- relation.first ? true : false
end
+
+ relation.first ? true : false
end
protected
@@ -222,7 +224,7 @@ module ActiveRecord
end
def construct_limited_ids_condition(relation)
- orders = relation.order_values.join(", ")
+ orders = relation.order_values
values = @klass.connection.distinct("#{@klass.connection.quote_table_name @klass.table_name}.#{@klass.primary_key}", orders)
ids_array = relation.select(values).collect {|row| row[@klass.primary_key]}
diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb
index 3fc596e02a..ba99800fb2 100644
--- a/activerecord/lib/active_record/session_store.rb
+++ b/activerecord/lib/active_record/session_store.rb
@@ -228,7 +228,7 @@ module ActiveRecord
@session_id = attributes[:session_id]
@data = attributes[:data]
@marshaled_data = attributes[:marshaled_data]
- @new_record = @marshaled_data.nil?
+ @persisted = !@marshaled_data.nil?
end
# Lazy-unmarshal session state.
@@ -252,8 +252,8 @@ module ActiveRecord
marshaled_data = self.class.marshal(data)
connect = connection
- if @new_record
- @new_record = false
+ unless @persisted
+ @persisted = true
connect.update <<-end_sql, 'Create session'
INSERT INTO #{table_name} (
#{connect.quote_column_name(session_id_column)},
@@ -272,7 +272,7 @@ module ActiveRecord
end
def destroy
- return if @new_record
+ return unless @persisted
connect = connection
connect.delete <<-end_sql, 'Destroy session'
@@ -321,6 +321,7 @@ module ActiveRecord
if sid = current_session_id(env)
Base.silence do
get_session_model(env, sid).destroy
+ env[SESSION_RECORD_KEY] = nil
end
end
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index ab737f0f88..8c94d1a2bc 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -242,7 +242,7 @@ module ActiveRecord
with_transaction_returning_status { super }
end
- # Reset id and @new_record if the transaction rolls back.
+ # Reset id and @persisted if the transaction rolls back.
def rollback_active_record_state!
remember_transaction_record_state
yield
@@ -297,9 +297,9 @@ module ActiveRecord
# Save the new record state and id of a record so it can be restored later if a transaction fails.
def remember_transaction_record_state #:nodoc
@_start_transaction_state ||= {}
- unless @_start_transaction_state.include?(:new_record)
+ unless @_start_transaction_state.include?(:persisted)
@_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key)
- @_start_transaction_state[:new_record] = @new_record
+ @_start_transaction_state[:persisted] = @persisted
end
unless @_start_transaction_state.include?(:destroyed)
@_start_transaction_state[:destroyed] = @destroyed
@@ -323,7 +323,7 @@ module ActiveRecord
restore_state = remove_instance_variable(:@_start_transaction_state)
if restore_state
@attributes = @attributes.dup if @attributes.frozen?
- @new_record = restore_state[:new_record]
+ @persisted = restore_state[:persisted]
@destroyed = restore_state[:destroyed]
if restore_state[:id]
self.id = restore_state[:id]
@@ -345,11 +345,11 @@ module ActiveRecord
def transaction_include_action?(action) #:nodoc
case action
when :create
- transaction_record_state(:new_record)
+ transaction_record_state(:new_record) || !transaction_record_state(:persisted)
when :destroy
destroyed?
when :update
- !(transaction_record_state(:new_record) || destroyed?)
+ !(transaction_record_state(:new_record) || !transaction_record_state(:persisted) || destroyed?)
end
end
end
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index f367315b22..ee45fcdf35 100644
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -51,7 +51,7 @@ module ActiveRecord
# Runs all the specified validations and returns true if no errors were added otherwise false.
def valid?(context = nil)
- context ||= (new_record? ? :create : :update)
+ context ||= (persisted? ? :update : :create)
output = super(context)
errors.empty? && output
end
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index cb1d2ae421..3eba7510ac 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -31,7 +31,7 @@ module ActiveRecord
relation = relation.where(scope_item => scope_value)
end
- unless record.new_record?
+ if record.persisted?
# TODO : This should be in Arel
relation = relation.where("#{record.class.quoted_table_name}.#{record.class.primary_key} <> ?", record.send(:id))
end
@@ -154,33 +154,25 @@ module ActiveRecord
# | # title!
#
# This could even happen if you use transactions with the 'serializable'
- # isolation level. There are several ways to get around this problem:
+ # isolation level. The best way to work around this problem is to add a unique
+ # index to the database table using
+ # ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the
+ # rare case that a race condition occurs, the database will guarantee
+ # the field's uniqueness.
#
- # - By locking the database table before validating, and unlocking it after
- # saving. However, table locking is very expensive, and thus not
- # recommended.
- # - By locking a lock file before validating, and unlocking it after saving.
- # This does not work if you've scaled your Rails application across
- # multiple web servers (because they cannot share lock files, or cannot
- # do that efficiently), and thus not recommended.
- # - Creating a unique index on the field, by using
- # ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the
- # rare case that a race condition occurs, the database will guarantee
- # the field's uniqueness.
+ # When the database catches such a duplicate insertion,
+ # ActiveRecord::Base#save will raise an ActiveRecord::StatementInvalid
+ # exception. You can either choose to let this error propagate (which
+ # will result in the default Rails exception page being shown), or you
+ # can catch it and restart the transaction (e.g. by telling the user
+ # that the title already exists, and asking him to re-enter the title).
+ # This technique is also known as optimistic concurrency control:
+ # http://en.wikipedia.org/wiki/Optimistic_concurrency_control
#
- # When the database catches such a duplicate insertion,
- # ActiveRecord::Base#save will raise an ActiveRecord::StatementInvalid
- # exception. You can either choose to let this error propagate (which
- # will result in the default Rails exception page being shown), or you
- # can catch it and restart the transaction (e.g. by telling the user
- # that the title already exists, and asking him to re-enter the title).
- # This technique is also known as optimistic concurrency control:
- # http://en.wikipedia.org/wiki/Optimistic_concurrency_control
- #
- # Active Record currently provides no way to distinguish unique
- # index constraint errors from other types of database errors, so you
- # will have to parse the (database-specific) exception message to detect
- # such a case.
+ # Active Record currently provides no way to distinguish unique
+ # index constraint errors from other types of database errors, so you
+ # will have to parse the (database-specific) exception message to detect
+ # such a case.
#
def validates_uniqueness_of(*attr_names)
validates_with UniquenessValidator, _merge_attributes(attr_names)
diff --git a/activerecord/test/cases/adapters/mysql/connection_test.rb b/activerecord/test/cases/adapters/mysql/connection_test.rb
index 67bd8ec7e0..62ffde558f 100644
--- a/activerecord/test/cases/adapters/mysql/connection_test.rb
+++ b/activerecord/test/cases/adapters/mysql/connection_test.rb
@@ -49,18 +49,18 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
def test_exec_no_binds
- @connection.exec('drop table if exists ex')
- @connection.exec(<<-eosql)
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
- result = @connection.exec('SELECT id, data FROM ex')
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
- @connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @connection.exec('SELECT id, data FROM ex')
+ @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
@@ -68,13 +68,13 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
def test_exec_with_binds
- @connection.exec('drop table if exists ex')
- @connection.exec(<<-eosql)
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
- @connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @connection.exec(
+ @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[nil, 1]])
assert_equal 1, result.rows.length
@@ -84,15 +84,15 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
def test_exec_typecasts_bind_vals
- @connection.exec('drop table if exists ex')
- @connection.exec(<<-eosql)
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
- @connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
column = @connection.columns('ex').find { |col| col.name == 'id' }
- result = @connection.exec(
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[column, '1-fuu']])
assert_equal 1, result.rows.length
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index b0fd2273df..b0a4a4e39d 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -5,8 +5,8 @@ module ActiveRecord
class PostgreSQLAdapterTest < ActiveRecord::TestCase
def setup
@connection = ActiveRecord::Base.connection
- @connection.exec('drop table if exists ex')
- @connection.exec('create table ex(id serial primary key, data character varying(255))')
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query('create table ex(id serial primary key, data character varying(255))')
end
def test_table_alias_length
@@ -16,14 +16,14 @@ module ActiveRecord
end
def test_exec_no_binds
- result = @connection.exec('SELECT id, data FROM ex')
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
string = @connection.quote('foo')
- @connection.exec("INSERT INTO ex (id, data) VALUES (1, #{string})")
- result = @connection.exec('SELECT id, data FROM ex')
+ @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
@@ -32,8 +32,8 @@ module ActiveRecord
def test_exec_with_binds
string = @connection.quote('foo')
- @connection.exec("INSERT INTO ex (id, data) VALUES (1, #{string})")
- result = @connection.exec(
+ @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = $1', nil, [[nil, 1]])
assert_equal 1, result.rows.length
@@ -44,10 +44,10 @@ module ActiveRecord
def test_exec_typecasts_bind_vals
string = @connection.quote('foo')
- @connection.exec("INSERT INTO ex (id, data) VALUES (1, #{string})")
+ @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
column = @connection.columns('ex').find { |col| col.name == 'id' }
- result = @connection.exec(
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = $1', nil, [[column, '1-fuu']])
assert_equal 1, result.rows.length
diff --git a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
index 881631fb19..d5e1838543 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
@@ -55,7 +55,7 @@ class SchemaAuthorizationTest < ActiveRecord::TestCase
set_session_auth
USERS.each do |u|
set_session_auth u
- assert_equal u, @connection.exec("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
+ assert_equal u, @connection.exec_query("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
set_session_auth
end
end
@@ -67,7 +67,7 @@ class SchemaAuthorizationTest < ActiveRecord::TestCase
USERS.each do |u|
@connection.clear_cache!
set_session_auth u
- assert_equal u, @connection.exec("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
+ assert_equal u, @connection.exec_query("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
set_session_auth
end
end
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
index 973c51f3d7..234696adeb 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -58,24 +58,24 @@ module ActiveRecord
end
def test_exec_no_binds
- @conn.exec('create table ex(id int, data string)')
- result = @conn.exec('SELECT id, data FROM ex')
+ @conn.exec_query('create table ex(id int, data string)')
+ result = @conn.exec_query('SELECT id, data FROM ex')
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
- @conn.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @conn.exec('SELECT id, data FROM ex')
+ @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @conn.exec_query('SELECT id, data FROM ex')
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
assert_equal [[1, 'foo']], result.rows
end
- def test_exec_with_binds
- @conn.exec('create table ex(id int, data string)')
- @conn.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @conn.exec(
+ def test_exec_query_with_binds
+ @conn.exec_query('create table ex(id int, data string)')
+ @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @conn.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[nil, 1]])
assert_equal 1, result.rows.length
@@ -84,12 +84,12 @@ module ActiveRecord
assert_equal [[1, 'foo']], result.rows
end
- def test_exec_typecasts_bind_vals
- @conn.exec('create table ex(id int, data string)')
- @conn.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ def test_exec_query_typecasts_bind_vals
+ @conn.exec_query('create table ex(id int, data string)')
+ @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
column = @conn.columns('ex').find { |col| col.name == 'id' }
- result = @conn.exec(
+ result = @conn.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[column, '1-fuu']])
assert_equal 1, result.rows.length
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index 0fa4328826..1b0c00bd5a 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -285,10 +285,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
final_cut = Client.new("name" => "Final Cut")
firm = Firm.find(1)
final_cut.firm = firm
- assert final_cut.new_record?
+ assert !final_cut.persisted?
assert final_cut.save
- assert !final_cut.new_record?
- assert !firm.new_record?
+ assert final_cut.persisted?
+ assert firm.persisted?
assert_equal firm, final_cut.firm
assert_equal firm, final_cut.firm(true)
end
@@ -297,10 +297,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
final_cut = Client.new("name" => "Final Cut")
firm = Firm.find(1)
final_cut.firm_with_primary_key = firm
- assert final_cut.new_record?
+ assert !final_cut.persisted?
assert final_cut.save
- assert !final_cut.new_record?
- assert !firm.new_record?
+ assert final_cut.persisted?
+ assert firm.persisted?
assert_equal firm, final_cut.firm_with_primary_key
assert_equal firm, final_cut.firm_with_primary_key(true)
end
diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
index 271bb92ee8..37c6f354a8 100644
--- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
+++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
@@ -137,7 +137,7 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
end
def test_eager_association_loading_with_multiple_stis_and_order
- author = Author.find(:first, :include => { :posts => [ :special_comments , :very_special_comment ] }, :order => 'authors.name, comments.body, very_special_comments_posts.body', :conditions => 'posts.id = 4')
+ author = Author.find(:first, :include => { :posts => [ :special_comments , :very_special_comment ] }, :order => ['authors.name', 'comments.body', 'very_special_comments_posts.body'], :conditions => 'posts.id = 4')
assert_equal authors(:david), author
assert_no_queries do
author.posts.first.special_comments
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 2d8e02e398..b559c9ddad 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -584,8 +584,8 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
def test_limited_eager_with_multiple_order_columns
- assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1)
- assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
+ assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => ['UPPER(posts.title)', 'posts.id'], :limit => 2, :offset => 1)
+ assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => ['UPPER(posts.title) DESC', 'posts.id'], :limit => 2, :offset => 1)
end
def test_limited_eager_with_numeric_in_association
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index 7e070e1746..c55523de38 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -251,10 +251,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
no_of_projects = Project.count
aredridel = Developer.new("name" => "Aredridel")
aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
- assert aredridel.new_record?
- assert p.new_record?
+ assert !aredridel.persisted?
+ assert !p.persisted?
assert aredridel.save
- assert !aredridel.new_record?
+ assert aredridel.persisted?
assert_equal no_of_devels+1, Developer.count
assert_equal no_of_projects+1, Project.count
assert_equal 2, aredridel.projects.size
@@ -288,9 +288,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal devel.projects.last, proj
assert devel.projects.loaded?
- assert proj.new_record?
+ assert !proj.persisted?
devel.save
- assert !proj.new_record?
+ assert proj.persisted?
assert_equal devel.projects.last, proj
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
end
@@ -300,10 +300,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
proj1 = devel.projects.build(:name => "Make bed")
proj2 = devel.projects.build(:name => "Lie in it")
assert_equal devel.projects.last, proj2
- assert proj2.new_record?
+ assert !proj2.persisted?
devel.save
- assert !devel.new_record?
- assert !proj2.new_record?
+ assert devel.persisted?
+ assert proj2.persisted?
assert_equal devel.projects.last, proj2
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
end
@@ -316,7 +316,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal devel.projects.last, proj
assert !devel.projects.loaded?
- assert !proj.new_record?
+ assert proj.persisted?
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
end
@@ -325,10 +325,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
proj1 = devel.projects.build(:name => "Make bed")
proj2 = devel.projects.build(:name => "Lie in it")
assert_equal devel.projects.last, proj2
- assert proj2.new_record?
+ assert !proj2.persisted?
devel.save
- assert !devel.new_record?
- assert !proj2.new_record?
+ assert devel.persisted?
+ assert proj2.persisted?
assert_equal devel.projects.last, proj2
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
end
@@ -343,7 +343,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
# in Oracle '' is saved as null therefore need to save ' ' in not null column
another_post = categories(:general).post_with_conditions.create(:body => ' ')
- assert !another_post.new_record?
+ assert another_post.persisted?
assert_equal 'Yet Another Testing Title', another_post.title
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index c9f00fd737..e9c119b823 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -187,7 +187,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
another = author.posts.find_or_create_by_title_and_body("Another Post", "This is the Body")
assert_equal number_of_posts + 1, Post.count
assert_equal another, author.posts.find_or_create_by_title_and_body("Another Post", "This is the Body")
- assert !another.new_record?
+ assert another.persisted?
end
def test_cant_save_has_many_readonly_association
@@ -453,7 +453,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert !company.clients_of_firm.loaded?
assert_equal "Another Client", new_client.name
- assert new_client.new_record?
+ assert !new_client.persisted?
assert_equal new_client, company.clients_of_firm.last
end
@@ -508,7 +508,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert !company.clients_of_firm.loaded?
assert_equal "Another Client", new_client.name
- assert new_client.new_record?
+ assert !new_client.persisted?
assert_equal new_client, company.clients_of_firm.last
end
@@ -543,7 +543,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_create
force_signal37_to_load_all_clients_of_firm
new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
- assert !new_client.new_record?
+ assert new_client.persisted?
assert_equal new_client, companies(:first_firm).clients_of_firm.last
assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
end
@@ -563,7 +563,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
the_client = companies(:first_firm).clients.find_or_initialize_by_name("Yet another client")
assert_equal companies(:first_firm).id, the_client.firm_id
assert_equal "Yet another client", the_client.name
- assert the_client.new_record?
+ assert !the_client.persisted?
end
def test_find_or_create_updates_size
@@ -752,7 +752,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
another_ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.create
- assert !another_ms_client.new_record?
+ assert another_ms_client.persisted?
assert_equal 'Microsoft', another_ms_client.name
end
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index b522be3fe0..6fbeff8aa9 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -268,7 +268,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_assignment_before_child_saved
firm = Firm.find(1)
firm.account = a = Account.new("credit_limit" => 1000)
- assert !a.new_record?
+ assert a.persisted?
assert_equal a, firm.account
assert_equal a, firm.account
assert_equal a, firm.account(true)
@@ -323,7 +323,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_create_respects_hash_condition
account = companies(:first_firm).create_account_limit_500_with_hash_conditions
- assert !account.new_record?
+ assert account.persisted?
assert_equal 500, account.credit_limit
end
diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb
index 7a22ce4dad..96edcfbb35 100644
--- a/activerecord/test/cases/associations/join_model_test.rb
+++ b/activerecord/test/cases/associations/join_model_test.rb
@@ -450,11 +450,11 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
new_tag = Tag.new(:name => "new")
saved_post.tags << new_tag
- assert !new_tag.new_record? #consistent with habtm!
- assert !saved_post.new_record?
+ assert new_tag.persisted? #consistent with habtm!
+ assert saved_post.persisted?
assert saved_post.tags.include?(new_tag)
- assert !new_tag.new_record?
+ assert new_tag.persisted?
assert saved_post.reload.tags(true).include?(new_tag)
@@ -462,16 +462,16 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
saved_tag = tags(:general)
new_post.tags << saved_tag
- assert new_post.new_record?
- assert !saved_tag.new_record?
+ assert !new_post.persisted?
+ assert saved_tag.persisted?
assert new_post.tags.include?(saved_tag)
new_post.save!
- assert !new_post.new_record?
+ assert new_post.persisted?
assert new_post.reload.tags(true).include?(saved_tag)
- assert posts(:thinking).tags.build.new_record?
- assert posts(:thinking).tags.new.new_record?
+ assert !posts(:thinking).tags.build.persisted?
+ assert !posts(:thinking).tags.new.persisted?
end
def test_create_associate_when_adding_to_has_many_through
diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb
index 89be94c81f..459f9fa55c 100644
--- a/activerecord/test/cases/autosave_association_test.rb
+++ b/activerecord/test/cases/autosave_association_test.rb
@@ -83,7 +83,7 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
assert !firm.build_account_using_primary_key.valid?
assert firm.save
- assert firm.account_using_primary_key.new_record?
+ assert !firm.account_using_primary_key.persisted?
end
def test_save_fails_for_invalid_has_one
@@ -114,10 +114,10 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
account = firm.account.build("credit_limit" => 1000)
assert_equal account, firm.account
- assert account.new_record?
+ assert !account.persisted?
assert firm.save
assert_equal account, firm.account
- assert !account.new_record?
+ assert account.persisted?
end
def test_build_before_either_saved
@@ -125,16 +125,16 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
firm.account = account = Account.new("credit_limit" => 1000)
assert_equal account, firm.account
- assert account.new_record?
+ assert !account.persisted?
assert firm.save
assert_equal account, firm.account
- assert !account.new_record?
+ assert account.persisted?
end
def test_assignment_before_parent_saved
firm = Firm.new("name" => "GlobalMegaCorp")
firm.account = a = Account.find(1)
- assert firm.new_record?
+ assert !firm.persisted?
assert_equal a, firm.account
assert firm.save
assert_equal a, firm.account
@@ -144,12 +144,12 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
def test_assignment_before_either_saved
firm = Firm.new("name" => "GlobalMegaCorp")
firm.account = a = Account.new("credit_limit" => 1000)
- assert firm.new_record?
- assert a.new_record?
+ assert !firm.persisted?
+ assert !a.persisted?
assert_equal a, firm.account
assert firm.save
- assert !firm.new_record?
- assert !a.new_record?
+ assert firm.persisted?
+ assert a.persisted?
assert_equal a, firm.account
assert_equal a, firm.account(true)
end
@@ -203,7 +203,7 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
assert !client.firm.valid?
assert client.save
- assert client.firm.new_record?
+ assert !client.firm.persisted?
end
def test_save_fails_for_invalid_belongs_to
@@ -232,10 +232,10 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
apple = Firm.new("name" => "Apple")
client.firm = apple
assert_equal apple, client.firm
- assert apple.new_record?
+ assert !apple.persisted?
assert client.save
assert apple.save
- assert !apple.new_record?
+ assert apple.persisted?
assert_equal apple, client.firm
assert_equal apple, client.firm(true)
end
@@ -244,11 +244,11 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
final_cut = Client.new("name" => "Final Cut")
apple = Firm.new("name" => "Apple")
final_cut.firm = apple
- assert final_cut.new_record?
- assert apple.new_record?
+ assert !final_cut.persisted?
+ assert !apple.persisted?
assert final_cut.save
- assert !final_cut.new_record?
- assert !apple.new_record?
+ assert final_cut.persisted?
+ assert apple.persisted?
assert_equal apple, final_cut.firm
assert_equal apple, final_cut.firm(true)
end
@@ -348,10 +348,10 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_invalid_adding
firm = Firm.find(1)
assert !(firm.clients_of_firm << c = Client.new)
- assert c.new_record?
+ assert !c.persisted?
assert !firm.valid?
assert !firm.save
- assert c.new_record?
+ assert !c.persisted?
end
def test_invalid_adding_before_save
@@ -359,12 +359,12 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
no_of_clients = Client.count
new_firm = Firm.new("name" => "A New Firm, Inc")
new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")])
- assert c.new_record?
+ assert !c.persisted?
assert !c.valid?
assert !new_firm.valid?
assert !new_firm.save
- assert c.new_record?
- assert new_firm.new_record?
+ assert !c.persisted?
+ assert !new_firm.persisted?
end
def test_invalid_adding_with_validate_false
@@ -375,7 +375,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
assert firm.valid?
assert !client.valid?
assert firm.save
- assert client.new_record?
+ assert !client.persisted?
end
def test_valid_adding_with_validate_false
@@ -386,22 +386,22 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
assert firm.valid?
assert client.valid?
- assert client.new_record?
+ assert !client.persisted?
firm.unvalidated_clients_of_firm << client
assert firm.save
- assert !client.new_record?
+ assert client.persisted?
assert_equal no_of_clients + 1, Client.count
end
def test_invalid_build
new_client = companies(:first_firm).clients_of_firm.build
- assert new_client.new_record?
+ assert !new_client.persisted?
assert !new_client.valid?
assert_equal new_client, companies(:first_firm).clients_of_firm.last
assert !companies(:first_firm).save
- assert new_client.new_record?
+ assert !new_client.persisted?
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
end
@@ -420,8 +420,8 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
assert_equal no_of_firms, Firm.count # Firm was not saved to database.
assert_equal no_of_clients, Client.count # Clients were not saved to database.
assert new_firm.save
- assert !new_firm.new_record?
- assert !c.new_record?
+ assert new_firm.persisted?
+ assert c.persisted?
assert_equal new_firm, c.firm
assert_equal no_of_firms + 1, Firm.count # Firm was saved to database.
assert_equal no_of_clients + 2, Client.count # Clients were saved to database.
@@ -455,7 +455,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
company.name += '-changed'
assert_queries(2) { assert company.save }
- assert !new_client.new_record?
+ assert new_client.persisted?
assert_equal 2, company.clients_of_firm(true).size
end
@@ -475,7 +475,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
company.name += '-changed'
assert_queries(2) { assert company.save }
- assert !new_client.new_record?
+ assert new_client.persisted?
assert_equal 2, company.clients_of_firm(true).size
end
@@ -507,62 +507,62 @@ class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase
new_account = Account.new("credit_limit" => 1000)
new_firm = Firm.new("name" => "some firm")
- assert new_firm.new_record?
+ assert !new_firm.persisted?
new_account.firm = new_firm
new_account.save!
- assert !new_firm.new_record?
+ assert new_firm.persisted?
new_account = Account.new("credit_limit" => 1000)
new_autosaved_firm = Firm.new("name" => "some firm")
- assert new_autosaved_firm.new_record?
+ assert !new_autosaved_firm.persisted?
new_account.unautosaved_firm = new_autosaved_firm
new_account.save!
- assert new_autosaved_firm.new_record?
+ assert !new_autosaved_firm.persisted?
end
def test_autosave_new_record_on_has_one_can_be_disabled_per_relationship
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
- assert account.new_record?
+ assert !account.persisted?
firm.account = account
firm.save!
- assert !account.new_record?
+ assert account.persisted?
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
firm.unautosaved_account = account
- assert account.new_record?
+ assert !account.persisted?
firm.unautosaved_account = account
firm.save!
- assert account.new_record?
+ assert !account.persisted?
end
def test_autosave_new_record_on_has_many_can_be_disabled_per_relationship
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
- assert account.new_record?
+ assert !account.persisted?
firm.accounts << account
firm.save!
- assert !account.new_record?
+ assert account.persisted?
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
- assert account.new_record?
+ assert !account.persisted?
firm.unautosaved_accounts << account
firm.save!
- assert account.new_record?
+ assert !account.persisted?
end
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index ceb1272862..9f2b0c9c86 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -656,8 +656,8 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_new_record_returns_boolean
- assert_equal true, Topic.new.new_record?
- assert_equal false, Topic.find(1).new_record?
+ assert_equal false, Topic.new.persisted?
+ assert_equal true, Topic.find(1).persisted?
end
def test_clone
@@ -665,7 +665,7 @@ class BasicsTest < ActiveRecord::TestCase
cloned_topic = nil
assert_nothing_raised { cloned_topic = topic.clone }
assert_equal topic.title, cloned_topic.title
- assert cloned_topic.new_record?
+ assert !cloned_topic.persisted?
# test if the attributes have been cloned
topic.title = "a"
@@ -684,7 +684,7 @@ class BasicsTest < ActiveRecord::TestCase
# test if saved clone object differs from original
cloned_topic.save
- assert !cloned_topic.new_record?
+ assert cloned_topic.persisted?
assert_not_equal cloned_topic.id, topic.id
cloned_topic.reload
@@ -700,7 +700,7 @@ class BasicsTest < ActiveRecord::TestCase
assert_nothing_raised { clone = dev.clone }
assert_kind_of DeveloperSalary, clone.salary
assert_equal dev.salary.amount, clone.salary.amount
- assert clone.new_record?
+ assert !clone.persisted?
# test if the attributes have been cloned
original_amount = clone.salary.amount
@@ -708,7 +708,7 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal original_amount, clone.salary.amount
assert clone.save
- assert !clone.new_record?
+ assert clone.persisted?
assert_not_equal clone.id, dev.id
end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index c058196078..87ec999b03 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -726,7 +726,7 @@ class FinderTest < ActiveRecord::TestCase
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.new_record?
+ assert sig38.persisted?
end
def test_find_or_create_from_two_attributes
@@ -734,7 +734,7 @@ class FinderTest < ActiveRecord::TestCase
another = Topic.find_or_create_by_title_and_author_name("Another topic","John")
assert_equal number_of_topics + 1, Topic.count
assert_equal another, Topic.find_or_create_by_title_and_author_name("Another topic", "John")
- assert !another.new_record?
+ assert another.persisted?
end
def test_find_or_create_from_two_attributes_with_one_being_an_aggregate
@@ -742,7 +742,7 @@ class FinderTest < ActiveRecord::TestCase
created_customer = Customer.find_or_create_by_balance_and_name(Money.new(123), "Elizabeth")
assert_equal number_of_customers + 1, Customer.count
assert_equal created_customer, Customer.find_or_create_by_balance(Money.new(123), "Elizabeth")
- assert !created_customer.new_record?
+ assert created_customer.persisted?
end
def test_find_or_create_from_one_attribute_and_hash
@@ -750,7 +750,7 @@ class FinderTest < ActiveRecord::TestCase
sig38 = Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23})
assert_equal number_of_companies + 1, Company.count
assert_equal sig38, Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23})
- assert !sig38.new_record?
+ assert sig38.persisted?
assert_equal "38signals", sig38.name
assert_equal 17, sig38.firm_id
assert_equal 23, sig38.client_of
@@ -761,7 +761,7 @@ class FinderTest < ActiveRecord::TestCase
created_customer = Customer.find_or_create_by_balance(Money.new(123))
assert_equal number_of_customers + 1, Customer.count
assert_equal created_customer, Customer.find_or_create_by_balance(Money.new(123))
- assert !created_customer.new_record?
+ assert created_customer.persisted?
end
def test_find_or_create_from_one_aggregate_attribute_and_hash
@@ -771,7 +771,7 @@ class FinderTest < ActiveRecord::TestCase
created_customer = Customer.find_or_create_by_balance({:balance => balance, :name => name})
assert_equal number_of_customers + 1, Customer.count
assert_equal created_customer, Customer.find_or_create_by_balance({:balance => balance, :name => name})
- assert !created_customer.new_record?
+ assert created_customer.persisted?
assert_equal balance, created_customer.balance
assert_equal name, created_customer.name
end
@@ -779,13 +779,13 @@ class FinderTest < ActiveRecord::TestCase
def test_find_or_initialize_from_one_attribute
sig38 = Company.find_or_initialize_by_name("38signals")
assert_equal "38signals", sig38.name
- assert sig38.new_record?
+ assert !sig38.persisted?
end
def test_find_or_initialize_from_one_aggregate_attribute
new_customer = Customer.find_or_initialize_by_balance(Money.new(123))
assert_equal 123, new_customer.balance.amount
- assert new_customer.new_record?
+ assert !new_customer.persisted?
end
def test_find_or_initialize_from_one_attribute_should_not_set_attribute_even_when_protected
@@ -793,7 +793,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_not_equal 1000, c.rating
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_from_one_attribute_should_not_set_attribute_even_when_protected
@@ -801,7 +801,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_not_equal 1000, c.rating
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_from_one_attribute_should_set_attribute_even_when_protected
@@ -809,7 +809,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_from_one_attribute_should_set_attribute_even_when_protected
@@ -817,7 +817,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_from_one_attribute_should_set_attribute_even_when_protected_and_also_set_the_hash
@@ -825,7 +825,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_from_one_attribute_should_set_attribute_even_when_protected_and_also_set_the_hash
@@ -833,7 +833,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_should_set_protected_attributes_if_given_as_block
@@ -841,7 +841,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000.to_f, c.rating.to_f
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_should_set_protected_attributes_if_given_as_block
@@ -849,7 +849,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000.to_f, c.rating.to_f
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_create_should_work_with_block_on_first_call
@@ -860,21 +860,21 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000.to_f, c.rating.to_f
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_from_two_attributes
another = Topic.find_or_initialize_by_title_and_author_name("Another topic","John")
assert_equal "Another topic", another.title
assert_equal "John", another.author_name
- assert another.new_record?
+ assert !another.persisted?
end
def test_find_or_initialize_from_one_aggregate_attribute_and_one_not
new_customer = Customer.find_or_initialize_by_balance_and_name(Money.new(123), "Elizabeth")
assert_equal 123, new_customer.balance.amount
assert_equal "Elizabeth", new_customer.name
- assert new_customer.new_record?
+ assert !new_customer.persisted?
end
def test_find_or_initialize_from_one_attribute_and_hash
@@ -882,7 +882,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "38signals", sig38.name
assert_equal 17, sig38.firm_id
assert_equal 23, sig38.client_of
- assert sig38.new_record?
+ assert !sig38.persisted?
end
def test_find_or_initialize_from_one_aggregate_attribute_and_hash
@@ -891,7 +891,7 @@ class FinderTest < ActiveRecord::TestCase
new_customer = Customer.find_or_initialize_by_balance({:balance => balance, :name => name})
assert_equal balance, new_customer.balance
assert_equal name, new_customer.name
- assert new_customer.new_record?
+ assert !new_customer.persisted?
end
def test_find_with_bad_sql
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index f6ef155d66..52f26b71f5 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -48,6 +48,10 @@ end
ActiveRecord::Base.connection.class.class_eval do
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /SHOW FIELDS/]
+ # FIXME: this needs to be refactored so specific database can add their own
+ # ignored SQL. This ignored SQL is for Oracle.
+ IGNORED_SQL.concat [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from ((all|user)_tab_columns|(all|user)_triggers|(all|user)_constraints)/im]
+
def execute_with_query_record(sql, name = nil, &block)
$queries_executed ||= []
$queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
@@ -56,13 +60,13 @@ ActiveRecord::Base.connection.class.class_eval do
alias_method_chain :execute, :query_record
- def exec_with_query_record(sql, name = nil, binds = [], &block)
+ def exec_query_with_query_record(sql, name = nil, binds = [], &block)
$queries_executed ||= []
$queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
- exec_without_query_record(sql, name, binds, &block)
+ exec_query_without_query_record(sql, name, binds, &block)
end
- alias_method_chain :exec, :query_record
+ alias_method_chain :exec_query, :query_record
end
ActiveRecord::Base.connection.class.class_eval {
diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb
index 60f89da95e..92af53d56f 100644
--- a/activerecord/test/cases/nested_attributes_test.rb
+++ b/activerecord/test/cases/nested_attributes_test.rb
@@ -139,6 +139,14 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase
assert_equal 'gardening', interest.reload.topic
end
+ def test_reject_if_with_blank_nested_attributes_id
+ # When using a select list to choose an existing 'ship' id, with :include_blank => true
+ Pirate.accepts_nested_attributes_for :ship, :reject_if => proc {|attributes| attributes[:id].blank? }
+
+ pirate = Pirate.new(:catchphrase => "Stop wastin' me time")
+ pirate.ship_attributes = { :id => "" }
+ assert_nothing_raised(ActiveRecord::RecordNotFound) { pirate.save! }
+ end
end
class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
@@ -163,7 +171,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
@ship.destroy
@pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger' }
- assert @pirate.ship.new_record?
+ assert !@pirate.ship.persisted?
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
end
@@ -184,7 +192,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
def test_should_replace_an_existing_record_if_there_is_no_id
@pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger' }
- assert @pirate.ship.new_record?
+ assert !@pirate.ship.persisted?
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
assert_equal 'Nights Dirty Lightning', @ship.name
end
@@ -256,7 +264,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
def test_should_also_work_with_a_HashWithIndifferentAccess
@pirate.ship_attributes = HashWithIndifferentAccess.new(:id => @ship.id, :name => 'Davy Jones Gold Dagger')
- assert !@pirate.ship.new_record?
+ assert @pirate.ship.persisted?
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
end
@@ -348,7 +356,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
@pirate.destroy
@ship.reload.pirate_attributes = { :catchphrase => 'Arr' }
- assert @ship.pirate.new_record?
+ assert !@ship.pirate.persisted?
assert_equal 'Arr', @ship.pirate.catchphrase
end
@@ -369,7 +377,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
def test_should_replace_an_existing_record_if_there_is_no_id
@ship.reload.pirate_attributes = { :catchphrase => 'Arr' }
- assert @ship.pirate.new_record?
+ assert !@ship.pirate.persisted?
assert_equal 'Arr', @ship.pirate.catchphrase
assert_equal 'Aye', @pirate.catchphrase
end
@@ -458,7 +466,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
@pirate.delete
@ship.reload.attributes = { :update_only_pirate_attributes => { :catchphrase => 'Arr' } }
- assert @ship.update_only_pirate.new_record?
+ assert !@ship.update_only_pirate.persisted?
end
def test_should_update_existing_when_update_only_is_true_and_no_id_is_given
@@ -596,10 +604,10 @@ module NestedAttributesOnACollectionAssociationTests
association_getter => { 'foo' => { :name => 'Grace OMalley' }, 'bar' => { :name => 'Privateers Greed' }}
}
- assert @pirate.send(@association_name).first.new_record?
+ assert !@pirate.send(@association_name).first.persisted?
assert_equal 'Grace OMalley', @pirate.send(@association_name).first.name
- assert @pirate.send(@association_name).last.new_record?
+ assert !@pirate.send(@association_name).last.persisted?
assert_equal 'Privateers Greed', @pirate.send(@association_name).last.name
end
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb
index ffe6fb95b8..07262f56be 100644
--- a/activerecord/test/cases/persistence_test.rb
+++ b/activerecord/test/cases/persistence_test.rb
@@ -241,6 +241,15 @@ class PersistencesTest < ActiveRecord::TestCase
assert_nothing_raised { minimalistic.save }
end
+ def test_update_sti_type
+ assert_instance_of Reply, topics(:second)
+
+ topic = topics(:second).becomes(Topic)
+ assert_instance_of Topic, topic
+ topic.save!
+ assert_instance_of Topic, Topic.find(topic.id)
+ end
+
def test_delete
topic = Topic.find(1)
assert_equal topic, topic.delete, 'topic.delete did not return self'
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index f4f3dc4d5a..b44c716db8 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -1,4 +1,5 @@
require "cases/helper"
+require 'models/tag'
require 'models/tagging'
require 'models/post'
require 'models/topic'
@@ -17,7 +18,7 @@ require 'models/tyre'
class RelationTest < ActiveRecord::TestCase
fixtures :authors, :topics, :entrants, :developers, :companies, :developers_projects, :accounts, :categories, :categorizations, :posts, :comments,
- :taggings, :cars
+ :tags, :taggings, :cars
def test_bind_values
relation = Post.scoped
@@ -144,6 +145,16 @@ class RelationTest < ActiveRecord::TestCase
assert_equal entrants(:first).name, entrants.first.name
end
+ def test_finding_with_complex_order_and_limit
+ tags = Tag.includes(:taggings).order("REPLACE('abc', taggings.taggable_type, taggings.taggable_type)").limit(1).to_a
+ assert_equal 1, tags.length
+ end
+
+ def test_finding_with_complex_order
+ tags = Tag.includes(:taggings).order("REPLACE('abc', taggings.taggable_type, taggings.taggable_type)").to_a
+ assert_equal 2, tags.length
+ end
+
def test_finding_with_order_limit_and_offset
entrants = Entrant.order("id ASC").limit(2).offset(1)
@@ -372,7 +383,7 @@ class RelationTest < ActiveRecord::TestCase
lifo = authors.find_or_initialize_by_name('Lifo')
assert_equal "Lifo", lifo.name
- assert lifo.new_record?
+ assert !lifo.persisted?
assert_equal authors(:david), authors.find_or_initialize_by_name(:name => 'David')
end
@@ -382,7 +393,7 @@ class RelationTest < ActiveRecord::TestCase
lifo = authors.find_or_create_by_name('Lifo')
assert_equal "Lifo", lifo.name
- assert ! lifo.new_record?
+ assert lifo.persisted?
assert_equal authors(:david), authors.find_or_create_by_name(:name => 'David')
end
@@ -616,10 +627,10 @@ class RelationTest < ActiveRecord::TestCase
sparrow = birds.create
assert_kind_of Bird, sparrow
- assert sparrow.new_record?
+ assert !sparrow.persisted?
hen = birds.where(:name => 'hen').create
- assert ! hen.new_record?
+ assert hen.persisted?
assert_equal 'hen', hen.name
end
@@ -630,7 +641,7 @@ class RelationTest < ActiveRecord::TestCase
hen = birds.where(:name => 'hen').create!
assert_kind_of Bird, hen
- assert ! hen.new_record?
+ assert hen.persisted?
assert_equal 'hen', hen.name
end
diff --git a/activerecord/test/cases/session_store/sql_bypass.rb b/activerecord/test/cases/session_store/sql_bypass.rb
index f0ba166465..7402b2afd6 100644
--- a/activerecord/test/cases/session_store/sql_bypass.rb
+++ b/activerecord/test/cases/session_store/sql_bypass.rb
@@ -18,9 +18,9 @@ module ActiveRecord
assert !Session.table_exists?
end
- def test_new_record?
+ def test_persisted?
s = SqlBypass.new :data => 'foo', :session_id => 10
- assert s.new_record?, 'this is a new record!'
+ assert !s.persisted?, 'this is a new record!'
end
def test_not_loaded?
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 0fbcef4091..dd9de3510b 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -182,7 +182,7 @@ class TransactionTest < ActiveRecord::TestCase
:bonus_time => "2005-01-30t15:28:00.00+01:00",
:content => "Have a nice day",
:approved => false)
- new_record_snapshot = new_topic.new_record?
+ new_record_snapshot = !new_topic.persisted?
id_present = new_topic.has_attribute?(Topic.primary_key)
id_snapshot = new_topic.id
@@ -195,7 +195,7 @@ class TransactionTest < ActiveRecord::TestCase
flunk
rescue => e
assert_equal "Make the transaction rollback", e.message
- assert_equal new_record_snapshot, new_topic.new_record?, "The topic should have its old new_record value"
+ assert_equal new_record_snapshot, !new_topic.persisted?, "The topic should have its old persisted value"
assert_equal id_snapshot, new_topic.id, "The topic should have its old id"
assert_equal id_present, new_topic.has_attribute?(Topic.primary_key)
ensure
@@ -370,21 +370,21 @@ class TransactionTest < ActiveRecord::TestCase
assert topic_2.save
@first.save
@second.destroy
- assert_equal false, topic_1.new_record?
+ assert_equal true, topic_1.persisted?
assert_not_nil topic_1.id
- assert_equal false, topic_2.new_record?
+ assert_equal true, topic_2.persisted?
assert_not_nil topic_2.id
- assert_equal false, @first.new_record?
+ assert_equal true, @first.persisted?
assert_not_nil @first.id
assert_equal true, @second.destroyed?
raise ActiveRecord::Rollback
end
- assert_equal true, topic_1.new_record?
+ assert_equal false, topic_1.persisted?
assert_nil topic_1.id
- assert_equal true, topic_2.new_record?
+ assert_equal false, topic_2.persisted?
assert_nil topic_2.id
- assert_equal false, @first.new_record?
+ assert_equal true, @first.persisted?
assert_not_nil @first.id
assert_equal false, @second.destroyed?
end
diff --git a/activerecord/test/connections/native_oracle/connection.rb b/activerecord/test/connections/native_oracle/connection.rb
index c942036128..99f921879c 100644
--- a/activerecord/test/connections/native_oracle/connection.rb
+++ b/activerecord/test/connections/native_oracle/connection.rb
@@ -33,15 +33,3 @@ ActiveRecord::Base.configurations = {
ActiveRecord::Base.establish_connection 'arunit'
Course.establish_connection 'arunit2'
-# for assert_queries test helper
-ActiveRecord::Base.connection.class.class_eval do
- IGNORED_SELECT_SQL = [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from ((all|user)_tab_columns|(all|user)_triggers|(all|user)_constraints)/im]
-
- def select_with_query_record(sql, name = nil)
- $queries_executed ||= []
- $queries_executed << sql unless IGNORED_SELECT_SQL.any? { |r| sql =~ r }
- select_without_query_record(sql, name)
- end
-
- alias_method_chain :select, :query_record
-end
diff --git a/activerecord/test/models/eye.rb b/activerecord/test/models/eye.rb
index 77f17b578e..dc8ae2b3f6 100644
--- a/activerecord/test/models/eye.rb
+++ b/activerecord/test/models/eye.rb
@@ -17,7 +17,7 @@ class Eye < ActiveRecord::Base
after_save :trace_after_save2
def trace_after_create
- (@after_create_callbacks_stack ||= []) << iris.new_record?
+ (@after_create_callbacks_stack ||= []) << !iris.persisted?
end
alias trace_after_create2 trace_after_create
diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb
index d89c8cf381..f2c45053e7 100644
--- a/activerecord/test/models/pirate.rb
+++ b/activerecord/test/models/pirate.rb
@@ -48,7 +48,7 @@ class Pirate < ActiveRecord::Base
end
def reject_empty_ships_on_create(attributes)
- attributes.delete('_reject_me_if_new').present? && new_record?
+ attributes.delete('_reject_me_if_new').present? && !persisted?
end
attr_accessor :cancel_save_from_callback
diff --git a/activerecord/test/models/subject.rb b/activerecord/test/models/subject.rb
index d4b8b91de8..8e28f8b86b 100644
--- a/activerecord/test/models/subject.rb
+++ b/activerecord/test/models/subject.rb
@@ -8,7 +8,7 @@ class Subject < ActiveRecord::Base
protected
def set_email_address
- if self.new_record?
+ unless self.persisted?
self.author_email_address = 'test@test.com'
end
end
diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb
index 82d4b5997f..6496f36f7e 100644
--- a/activerecord/test/models/topic.rb
+++ b/activerecord/test/models/topic.rb
@@ -89,7 +89,7 @@ class Topic < ActiveRecord::Base
end
def set_email_address
- if self.new_record?
+ unless self.persisted?
self.author_email_address = 'test@test.com'
end
end
diff --git a/activeresource/CHANGELOG b/activeresource/CHANGELOG
index 24fe3072e0..386bafd7de 100644
--- a/activeresource/CHANGELOG
+++ b/activeresource/CHANGELOG
@@ -2,6 +2,10 @@
* No changes
+*Rails 3.0.2 (unreleased)*
+
+* No changes
+
*Rails 3.0.1 (October 15, 2010)*
* No Changes, just a version bump.
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 3b6a29f7d6..6e8cce0d27 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -4,6 +4,10 @@
* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
+*Rails 3.0.2 (unreleased)*
+
+* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
+
*Rails 3.0.1 (October 15, 2010)*
* No Changes, just a version bump.
diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb
index 84f6f29572..18182bbb40 100644
--- a/activesupport/lib/active_support/cache/file_store.rb
+++ b/activesupport/lib/active_support/cache/file_store.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/file/atomic'
require 'active_support/core_ext/string/conversions'
+require 'rack/utils'
module ActiveSupport
module Cache
@@ -11,8 +12,6 @@ module ActiveSupport
attr_reader :cache_path
DIR_FORMATTER = "%03X"
- ESCAPE_FILENAME_CHARS = /[^a-z0-9_.-]/i
- UNESCAPE_FILENAME_CHARS = /%[0-9A-F]{2}/
def initialize(cache_path, options = nil)
super(options)
@@ -136,7 +135,7 @@ module ActiveSupport
# Translate a key into a file path.
def key_file_path(key)
- fname = key.to_s.gsub(ESCAPE_FILENAME_CHARS){|match| "%#{match.ord.to_s(16).upcase}"}
+ fname = Rack::Utils.escape(key)
hash = Zlib.adler32(fname)
hash, dir_1 = hash.divmod(0x1000)
dir_2 = hash.modulo(0x1000)
@@ -156,7 +155,7 @@ module ActiveSupport
# Translate a file path into a key.
def file_path_key(path)
fname = path[cache_path.size, path.size].split(File::SEPARATOR, 4).last
- fname.gsub(UNESCAPE_FILENAME_CHARS){|match| $1.ord.to_s(16)}
+ Rack::Utils.unescape(fname)
end
# Delete empty directories in the cache.
diff --git a/activesupport/lib/active_support/core_ext/cgi.rb b/activesupport/lib/active_support/core_ext/cgi.rb
deleted file mode 100644
index 7279a3d4da..0000000000
--- a/activesupport/lib/active_support/core_ext/cgi.rb
+++ /dev/null
@@ -1 +0,0 @@
-require 'active_support/core_ext/cgi/escape_skipping_slashes'
diff --git a/activesupport/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb b/activesupport/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb
deleted file mode 100644
index d3c3575748..0000000000
--- a/activesupport/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require 'cgi'
-
-class CGI #:nodoc:
- if RUBY_VERSION >= '1.9'
- def self.escape_skipping_slashes(str)
- str = str.join('/') if str.respond_to? :join
- str.gsub(/([^ \/a-zA-Z0-9_.-])/n) do
- "%#{$1.unpack('H2' * $1.bytesize).join('%').upcase}"
- end.tr(' ', '+')
- end
- else
- def self.escape_skipping_slashes(str)
- str = str.join('/') if str.respond_to? :join
- str.gsub(/([^ \/a-zA-Z0-9_.-])/n) do
- "%#{$1.unpack('H2').first.upcase}"
- end.tr(' ', '+')
- end
- end
-end
diff --git a/activesupport/lib/active_support/core_ext/object/instance_variables.rb b/activesupport/lib/active_support/core_ext/object/instance_variables.rb
index 77a3cfc21d..eda9694614 100644
--- a/activesupport/lib/active_support/core_ext/object/instance_variables.rb
+++ b/activesupport/lib/active_support/core_ext/object/instance_variables.rb
@@ -30,35 +30,4 @@ class Object
else
alias_method :instance_variable_names, :instance_variables
end
-
- # Copies the instance variables of +object+ into +self+.
- #
- # Instance variable names in the +exclude+ array are ignored. If +object+
- # responds to <tt>protected_instance_variables</tt> the ones returned are
- # also ignored. For example, Rails controllers implement that method.
- #
- # In both cases strings and symbols are understood, and they have to include
- # the at sign.
- #
- # class C
- # def initialize(x, y, z)
- # @x, @y, @z = x, y, z
- # end
- #
- # def protected_instance_variables
- # %w(@z)
- # end
- # end
- #
- # a = C.new(0, 1, 2)
- # b = C.new(3, 4, 5)
- #
- # a.copy_instance_variables_from(b, [:@y])
- # # a is now: @x = 3, @y = 1, @z = 2
- def copy_instance_variables_from(object, exclude = []) #:nodoc:
- exclude += object.protected_instance_variables if object.respond_to? :protected_instance_variables
-
- vars = object.instance_variables.map(&:to_s) - exclude.map(&:to_s)
- vars.each { |name| instance_variable_set(name, object.instance_variable_get(name)) }
- end
end
diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb
index c406dd3c2e..06dd18966e 100644
--- a/activesupport/lib/active_support/hash_with_indifferent_access.rb
+++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -28,7 +28,7 @@ module ActiveSupport
end
def self.new_from_hash_copying_default(hash)
- ActiveSupport::HashWithIndifferentAccess.new(hash).tap do |new_hash|
+ new(hash).tap do |new_hash|
new_hash.default = hash.default
end
end
@@ -97,7 +97,9 @@ module ActiveSupport
# Returns an exact copy of the hash.
def dup
- HashWithIndifferentAccess.new(self)
+ self.class.new(self).tap do |new_hash|
+ new_hash.default = default
+ end
end
# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb
index 7f148dc853..8e157d3af4 100644
--- a/activesupport/lib/active_support/ordered_hash.rb
+++ b/activesupport/lib/active_support/ordered_hash.rb
@@ -137,6 +137,8 @@ module ActiveSupport
alias_method :each_pair, :each
+ alias_method :select, :find_all
+
def clear
super
@keys.clear
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index 93f5d5a0cc..6a7da8266c 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -73,7 +73,7 @@ module ActiveSupport
# Returns a <tt>Time.local()</tt> instance of the simultaneous time in your system's <tt>ENV['TZ']</tt> zone
def localtime
- utc.getlocal
+ utc.respond_to?(:getlocal) ? utc.getlocal : utc.to_time.getlocal
end
alias_method :getlocal, :localtime
diff --git a/activesupport/lib/active_support/xml_mini.rb b/activesupport/lib/active_support/xml_mini.rb
index b6a8cf3caf..cddfcddb57 100644
--- a/activesupport/lib/active_support/xml_mini.rb
+++ b/activesupport/lib/active_support/xml_mini.rb
@@ -126,9 +126,11 @@ module ActiveSupport
end
def rename_key(key, options = {})
- camelize = options.has_key?(:camelize) && options[:camelize]
+ camelize = options[:camelize]
dasherize = !options.has_key?(:dasherize) || options[:dasherize]
- key = key.camelize if camelize
+ if camelize
+ key = true == camelize ? key.camelize : key.camelize(camelize)
+ end
key = _dasherize(key) if dasherize
key
end
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index 28ef695a4b..579d5dad24 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -356,9 +356,13 @@ module CacheDeleteMatchedBehavior
def test_delete_matched
@cache.write("foo", "bar")
@cache.write("fu", "baz")
+ @cache.write("foo/bar", "baz")
+ @cache.write("fu/baz", "bar")
@cache.delete_matched(/oo/)
assert_equal false, @cache.exist?("foo")
assert_equal true, @cache.exist?("fu")
+ assert_equal false, @cache.exist?("foo/bar")
+ assert_equal true, @cache.exist?("fu/baz")
end
end
@@ -509,6 +513,11 @@ class FileStoreTest < ActiveSupport::TestCase
assert_nil old_cache.read('foo')
end
end
+
+ def test_key_transformation
+ key = @cache.send(:key_file_path, "views/index?id=1")
+ assert_equal "views/index?id=1", @cache.send(:file_path_key, key)
+ end
end
class MemoryStoreTest < ActiveSupport::TestCase
diff --git a/activesupport/test/core_ext/cgi_ext_test.rb b/activesupport/test/core_ext/cgi_ext_test.rb
deleted file mode 100644
index c80362e382..0000000000
--- a/activesupport/test/core_ext/cgi_ext_test.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require 'abstract_unit'
-require 'active_support/core_ext/cgi'
-
-class EscapeSkippingSlashesTest < Test::Unit::TestCase
- def test_array
- assert_equal 'hello/world', CGI.escape_skipping_slashes(%w(hello world))
- assert_equal 'hello+world/how/are/you', CGI.escape_skipping_slashes(['hello world', 'how', 'are', 'you'])
- end
-
- def test_typical
- assert_equal 'hi', CGI.escape_skipping_slashes('hi')
- assert_equal 'hi/world', CGI.escape_skipping_slashes('hi/world')
- assert_equal 'hi/world+you+funky+thing', CGI.escape_skipping_slashes('hi/world you funky thing')
- end
-end
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index bfcfddad47..d7b77e43bd 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -6,6 +6,9 @@ require 'active_support/ordered_hash'
require 'active_support/core_ext/object/conversions'
class HashExtTest < Test::Unit::TestCase
+ class IndifferentHash < HashWithIndifferentAccess
+ end
+
def setup
@strings = { 'a' => 1, 'b' => 2 }
@symbols = { :a => 1, :b => 2 }
@@ -267,7 +270,6 @@ class HashExtTest < Test::Unit::TestCase
assert_equal 1, h['first']
end
-
def test_indifferent_subhashes
h = {'user' => {'id' => 5}}.with_indifferent_access
['user', :user].each {|user| [:id, 'id'].each {|id| assert_equal 5, h[user][id], "h[#{user.inspect}][#{id.inspect}] should be 5"}}
@@ -276,6 +278,17 @@ class HashExtTest < Test::Unit::TestCase
['user', :user].each {|user| [:id, 'id'].each {|id| assert_equal 5, h[user][id], "h[#{user.inspect}][#{id.inspect}] should be 5"}}
end
+ def test_indifferent_duplication
+ # Should preserve default value
+ h = HashWithIndifferentAccess.new
+ h.default = '1234'
+ assert_equal h.default, h.dup.default
+
+ # Should preserve class for subclasses
+ h = IndifferentHash.new
+ assert_equal h.class, h.dup.class
+ end
+
def test_assert_valid_keys
assert_nothing_raised do
{ :failure => "stuff", :funny => "business" }.assert_valid_keys([ :failure, :funny ])
@@ -501,7 +514,7 @@ class HashExtToParamTests < Test::Unit::TestCase
def test_to_param_hash_escapes_its_keys_and_values
assert_equal 'param+1=A+string+with+%2F+characters+%26+that+should+be+%3F+escaped', { 'param 1' => 'A string with / characters & that should be ? escaped' }.to_param
end
-
+
def test_to_param_orders_by_key_in_ascending_order
assert_equal 'a=2&b=1&c=0', ActiveSupport::OrderedHash[*%w(b 1 c 0 a 2)].to_param
end
@@ -540,6 +553,13 @@ class HashToXmlTest < Test::Unit::TestCase
assert xml.include?(%(<Name>David</Name>))
end
+ def test_one_level_camelize_lower
+ xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:camelize => :lower))
+ assert_equal "<person>", xml.first(8)
+ assert xml.include?(%(<streetName>Paulina</streetName>))
+ assert xml.include?(%(<name>David</name>))
+ end
+
def test_one_level_with_types
xml = { :name => "David", :street => "Paulina", :age => 26, :age_in_millis => 820497600000, :moved_on => Date.new(2005, 11, 15), :resident => :yes }.to_xml(@xml_options)
assert_equal "<person>", xml.first(8)
diff --git a/activesupport/test/core_ext/object_and_class_ext_test.rb b/activesupport/test/core_ext/object_and_class_ext_test.rb
index 3ccf18f473..64f339ed90 100644
--- a/activesupport/test/core_ext/object_and_class_ext_test.rb
+++ b/activesupport/test/core_ext/object_and_class_ext_test.rb
@@ -82,37 +82,6 @@ class ObjectInstanceVariableTest < Test::Unit::TestCase
assert_equal %w(@bar @baz), @source.instance_variable_names.sort
end
- def test_copy_instance_variables_from_without_explicit_excludes
- assert_equal [], @dest.instance_variables
- @dest.copy_instance_variables_from(@source)
-
- assert_equal %w(@bar @baz), @dest.instance_variables.sort.map(&:to_s)
- %w(@bar @baz).each do |name|
- assert_equal @source.instance_variable_get(name).object_id,
- @dest.instance_variable_get(name).object_id
- end
- end
-
- def test_copy_instance_variables_from_with_explicit_excludes
- @dest.copy_instance_variables_from(@source, ['@baz'])
- assert !@dest.instance_variable_defined?('@baz')
- assert_equal 'bar', @dest.instance_variable_get('@bar')
- end
-
- def test_copy_instance_variables_automatically_excludes_protected_instance_variables
- @source.instance_variable_set(:@quux, 'quux')
- class << @source
- def protected_instance_variables
- ['@bar', :@quux]
- end
- end
-
- @dest.copy_instance_variables_from(@source)
- assert !@dest.instance_variable_defined?('@bar')
- assert !@dest.instance_variable_defined?('@quux')
- assert_equal 'baz', @dest.instance_variable_get('@baz')
- end
-
def test_instance_values
object = Object.new
object.instance_variable_set :@a, 1
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index 0bb2c4a39e..5579c27215 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -36,6 +36,10 @@ class TimeWithZoneTest < Test::Unit::TestCase
assert_equal @twz.object_id, @twz.in_time_zone(ActiveSupport::TimeZone['Eastern Time (US & Canada)']).object_id
end
+ def test_localtime
+ assert_equal @twz.localtime, @twz.utc.getlocal
+ end
+
def test_utc?
assert_equal false, @twz.utc?
assert_equal true, ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']).utc?
@@ -763,6 +767,13 @@ class TimeWithZoneMethodsForTimeAndDateTimeTest < Test::Unit::TestCase
end
end
+ def test_localtime
+ Time.zone_default = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ assert_equal @dt.in_time_zone.localtime, @dt.in_time_zone.utc.to_time.getlocal
+ ensure
+ Time.zone_default = nil
+ end
+
def test_use_zone
Time.zone = 'Alaska'
Time.use_zone 'Hawaii' do
diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb
index 50778b5864..72088854fc 100644
--- a/activesupport/test/ordered_hash_test.rb
+++ b/activesupport/test/ordered_hash_test.rb
@@ -109,6 +109,14 @@ class OrderedHashTest < Test::Unit::TestCase
assert_equal @keys, keys
end
+ def test_find_all
+ assert_equal @keys, @ordered_hash.find_all { true }.map(&:first)
+ end
+
+ def test_select
+ assert_equal @keys, @ordered_hash.select { true }.map(&:first)
+ end
+
def test_delete_if
copy = @ordered_hash.dup
copy.delete('pink')
diff --git a/activesupport/test/test_xml_mini.rb b/activesupport/test/test_xml_mini.rb
index 585eb15c6e..309fa234bf 100644
--- a/activesupport/test/test_xml_mini.rb
+++ b/activesupport/test/test_xml_mini.rb
@@ -14,14 +14,26 @@ class XmlMiniTest < Test::Unit::TestCase
assert_equal "my_key", ActiveSupport::XmlMini.rename_key("my_key", :dasherize => false)
end
- def test_rename_key_camelizes_with_camelize_true
- assert_equal "MyKey", ActiveSupport::XmlMini.rename_key("my_key", :camelize => true)
+ def test_rename_key_camelizes_with_camelize_false
+ assert_equal "my_key", ActiveSupport::XmlMini.rename_key("my_key", :camelize => false)
+ end
+
+ def test_rename_key_camelizes_with_camelize_nil
+ assert_equal "my_key", ActiveSupport::XmlMini.rename_key("my_key", :camelize => nil)
end
def test_rename_key_camelizes_with_camelize_true
assert_equal "MyKey", ActiveSupport::XmlMini.rename_key("my_key", :camelize => true)
end
+ def test_rename_key_lower_camelizes_with_camelize_lower
+ assert_equal "myKey", ActiveSupport::XmlMini.rename_key("my_key", :camelize => :lower)
+ end
+
+ def test_rename_key_lower_camelizes_with_camelize_upper
+ assert_equal "MyKey", ActiveSupport::XmlMini.rename_key("my_key", :camelize => :upper)
+ end
+
def test_rename_key_does_not_dasherize_leading_underscores
assert_equal "_id", ActiveSupport::XmlMini.rename_key("_id")
end
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index 9b1d264d2c..8c11b2a11a 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -395,39 +395,6 @@ C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
-h5. +copy_instance_variables_from(object, exclude = [])+
-
-Copies the instance variables of +object+ into +self+.
-
-Instance variable names in the +exclude+ array are ignored. If +object+
-responds to +protected_instance_variables+ the ones returned are
-also ignored. For example, Rails controllers implement that method.
-
-In both arrays strings and symbols are understood, and they have to include
-the at sign.
-
-<ruby>
-class C
- def initialize(x, y, z)
- @x, @y, @z = x, y, z
- end
-
- def protected_instance_variables
- %w(@z)
- end
-end
-
-a = C.new(0, 1, 2)
-b = C.new(3, 4, 5)
-
-a.copy_instance_variables_from(b, [:@y])
-# a is now: @x = 3, @y = 1, @z = 2
-</ruby>
-
-In the example +object+ and +self+ are of the same type, but they don't need to.
-
-NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
-
h4. Silencing Warnings, Streams, and Exceptions
The methods +silence_warnings+ and +enable_warnings+ change the value of +$VERBOSE+ accordingly for the duration of their block, and reset it afterwards:
diff --git a/railties/guides/source/api_documentation_guidelines.textile b/railties/guides/source/api_documentation_guidelines.textile
index 900b3fb5d5..e3ccd6396c 100644
--- a/railties/guides/source/api_documentation_guidelines.textile
+++ b/railties/guides/source/api_documentation_guidelines.textile
@@ -116,14 +116,12 @@ Use fixed-width fonts for:
* file names
<ruby>
-# Copies the instance variables of +object+ into +self+.
-#
-# Instance variable names in the +exclude+ array are ignored. If +object+
-# responds to <tt>protected_instance_variables</tt> the ones returned are
-# also ignored. For example, Rails controllers implement that method.
-# ...
-def copy_instance_variables_from(object, exclude = [])
- ...
+class Array
+ # Calls <tt>to_param</tt> on all its elements and joins the result with
+ # slashes. This is used by <tt>url_for</tt> in Action Pack.
+ def to_param
+ collect { |e| e.to_param }.join '/'
+ end
end
</ruby>
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index d84373cddf..182068071d 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -35,7 +35,6 @@ module Rails
#
class Application < Engine
autoload :Bootstrap, 'rails/application/bootstrap'
- autoload :Configurable, 'rails/application/configurable'
autoload :Configuration, 'rails/application/configuration'
autoload :Finisher, 'rails/application/finisher'
autoload :Railties, 'rails/application/railties'
diff --git a/railties/lib/rails/cli.rb b/railties/lib/rails/cli.rb
index c8d70d8ffa..2b32f7edf1 100644
--- a/railties/lib/rails/cli.rb
+++ b/railties/lib/rails/cli.rb
@@ -5,9 +5,6 @@ require 'rails/script_rails_loader'
# the rest of this script is not run.
Rails::ScriptRailsLoader.exec_script_rails!
-railties_path = File.expand_path('../../lib', __FILE__)
-$:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(railties_path)
-
require 'rails/ruby_version_check'
Signal.trap("INT") { puts; exit }
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 72bfe207d7..466a31c2a0 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -324,8 +324,8 @@ module Rails
# MyEngine::Engine.load_seed
#
class Engine < Railtie
- autoload :Configurable, "rails/engine/configurable"
autoload :Configuration, "rails/engine/configuration"
+ autoload :Railties, "rails/engine/railties"
class << self
attr_accessor :called_from, :isolated
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index 00a23a7b89..6e515756fe 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -48,6 +48,10 @@ module <%= app_const_base %>
# config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
<% end -%>
+<% if options[:skip_test_unit] -%>
+ config.generators.test_framework = false
+<% end -%>
+
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb
index c9e70468a1..d6ccfc496a 100644
--- a/railties/lib/rails/generators/resource_helpers.rb
+++ b/railties/lib/rails/generators/resource_helpers.rb
@@ -17,7 +17,7 @@ module Rails
def initialize(*args) #:nodoc:
super
- if name == name.pluralize && !options[:force_plural]
+ if name == name.pluralize && name.singularize != name.pluralize && !options[:force_plural]
unless ResourceHelpers.skip_warn
say "Plural version of the model detected, using singularized version. Override with --force-plural."
ResourceHelpers.skip_warn = true
diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb
index 6cbd1f21c0..d05e031f56 100644
--- a/railties/lib/rails/info.rb
+++ b/railties/lib/rails/info.rb
@@ -1,5 +1,4 @@
require "cgi"
-require "active_support/core_ext/cgi"
module Rails
module Info
diff --git a/railties/railties.gemspec b/railties/railties.gemspec
index d26c1bcdbc..c3793d3ac3 100644
--- a/railties/railties.gemspec
+++ b/railties/railties.gemspec
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
s.has_rdoc = false
s.add_dependency('rake', '>= 0.8.7')
- s.add_dependency('thor', '~> 0.14.3')
+ s.add_dependency('thor', '~> 0.14.4')
s.add_dependency('activesupport', version)
s.add_dependency('actionpack', version)
end
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index 8e527236ea..719550f9d9 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -38,5 +38,14 @@ module ApplicationTests
assert_match "Code LOC: 5 Test LOC: 0 Code to Test Ratio: 1:0.0",
Dir.chdir(app_path){ `rake stats` }
end
+
+ def test_rake_routes_output_strips_anchors_from_http_verbs
+ app_file "config/routes.rb", <<-RUBY
+ AppTemplate::Application.routes.draw do
+ get '/cart', :to => 'cart#show'
+ end
+ RUBY
+ assert_match 'cart GET /cart(.:format)', Dir.chdir(app_path){ `rake routes` }
+ end
end
end
diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb
index 55d5bd6f83..71b3619351 100644
--- a/railties/test/generators/resource_generator_test.rb
+++ b/railties/test/generators/resource_generator_test.rb
@@ -73,6 +73,11 @@ class ResourceGeneratorTest < Rails::Generators::TestCase
assert_no_match /Plural version of the model detected/, content
end
+ def test_mass_nouns_do_not_throw_warnings
+ content = run_generator ["sheep".freeze]
+ assert_no_match /Plural version of the model detected/, content
+ end
+
def test_route_is_removed_on_revoke
run_generator
run_generator ["account"], :behavior => :revoke