aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/abstract_controller/base.rb3
-rw-r--r--actionpack/lib/action_controller/test_case.rb6
-rw-r--r--actionview/lib/action_view/helpers/translation_helper.rb14
-rw-r--r--actionview/test/template/translation_helper_test.rb24
-rw-r--r--activerecord/lib/active_record/core.rb2
-rw-r--r--activerecord/lib/active_record/fixtures.rb2
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb4
-rw-r--r--activerecord/lib/active_record/transactions.rb2
-rw-r--r--activerecord/test/cases/attribute_methods_test.rb4
-rw-r--r--activerecord/test/cases/base_test.rb3
-rw-r--r--activerecord/test/cases/bind_parameter_test.rb10
-rw-r--r--activerecord/test/cases/migration/rename_table_test.rb38
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb2
-rw-r--r--activerecord/test/cases/secure_token_test.rb10
-rw-r--r--activerecord/test/cases/transactions_test.rb21
-rw-r--r--activerecord/test/schema/schema.rb2
-rw-r--r--guides/source/documents.yaml6
17 files changed, 109 insertions, 44 deletions
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb
index 5bb34daf81..8c7cec3561 100644
--- a/actionpack/lib/abstract_controller/base.rb
+++ b/actionpack/lib/abstract_controller/base.rb
@@ -86,8 +86,7 @@ module AbstractController
# And always exclude explicitly hidden actions
hidden_actions.to_a
- # Clear out AS callback method pollution
- Set.new(methods.reject { |method| method =~ /_one_time_conditions/ })
+ methods.to_set
end
end
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 2e6c58b83a..d30615fade 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -66,8 +66,10 @@ module ActionController
def reset_template_assertion
RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
- ivar = instance_variable_get("@_#{instance_variable}")
- ivar.clear if ivar
+ ivar_name = "@_#{instance_variable}"
+ if instance_variable_defined?(ivar_name)
+ instance_variable_get(ivar_name).clear
+ end
end
end
diff --git a/actionview/lib/action_view/helpers/translation_helper.rb b/actionview/lib/action_view/helpers/translation_helper.rb
index 8324f12a88..342361217c 100644
--- a/actionview/lib/action_view/helpers/translation_helper.rb
+++ b/actionview/lib/action_view/helpers/translation_helper.rb
@@ -40,12 +40,14 @@ module ActionView
remaining_defaults = Array(options.delete(:default))
options[:default] = remaining_defaults.shift if remaining_defaults.first.kind_of? String
- # If the user has specified rescue_format then pass it all through, otherwise use
- # raise and do the work ourselves
- options[:raise] ||= ActionView::Base.raise_on_missing_translations
-
- raise_error = options[:raise] || options.key?(:rescue_format)
- unless raise_error
+ # If the user has explicitly decided to NOT raise errors, pass that option to I18n.
+ # Otherwise, tell I18n to raise an exception, which we rescue further in this method.
+ # Note: `raise_error` refers to us re-raising the error in this method. I18n is forced to raise by default.
+ if options[:raise] == false || (options.key?(:rescue_format) && options[:rescue_format].nil?)
+ raise_error = false
+ options[:raise] = false
+ else
+ raise_error = options[:raise] || options[:rescue_format] || ActionView::Base.raise_on_missing_translations
options[:raise] = true
end
diff --git a/actionview/test/template/translation_helper_test.rb b/actionview/test/template/translation_helper_test.rb
index dea861c0e5..8fde478ac9 100644
--- a/actionview/test/template/translation_helper_test.rb
+++ b/actionview/test/template/translation_helper_test.rb
@@ -1,5 +1,13 @@
require 'abstract_unit'
+module I18n
+ class CustomExceptionHandler
+ def self.call(exception, locale, key, options)
+ 'from CustomExceptionHandler'
+ end
+ end
+end
+
class TranslationHelperTest < ActiveSupport::TestCase
include ActionView::Helpers::TranslationHelper
@@ -72,6 +80,22 @@ class TranslationHelperTest < ActiveSupport::TestCase
end
end
+ def test_uses_custom_exception_handler_when_specified
+ old_exception_handler = I18n.exception_handler
+ I18n.exception_handler = I18n::CustomExceptionHandler
+ assert_equal 'from CustomExceptionHandler', translate(:"translations.missing", raise: false)
+ ensure
+ I18n.exception_handler = old_exception_handler
+ end
+
+ def test_uses_custom_exception_handler_when_specified_for_html
+ old_exception_handler = I18n.exception_handler
+ I18n.exception_handler = I18n::CustomExceptionHandler
+ assert_equal 'from CustomExceptionHandler', translate(:"translations.missing_html", raise: false)
+ ensure
+ I18n.exception_handler = old_exception_handler
+ end
+
def test_i18n_translate_defaults_to_nil_rescue_format
expected = 'translation missing: en.translations.missing'
assert_equal expected, I18n.translate(:"translations.missing")
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 5c7c0feeb7..5a5139256d 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -276,11 +276,11 @@ module ActiveRecord
# User.new(first_name: 'Jamie')
def initialize(attributes = nil, options = {})
@attributes = self.class._default_attributes.dup
+ self.class.define_attribute_methods
init_internals
initialize_internals_callback
- self.class.define_attribute_methods
# +options+ argument is only needed to make protected_attributes gem easier to hook.
# Remove it when we drop support to this gem.
init_attributes(attributes, options) if attributes
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 3c71936c3b..5f6a75ebef 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -633,7 +633,7 @@ module ActiveRecord
# interpolate the fixture label
row.each do |key, value|
- row[key] = value.gsub("$LABEL", label) if value.is_a?(String)
+ row[key] = value.gsub("$LABEL", label.to_s) if value.is_a?(String)
end
# generate a primary key if necessary
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 6892cc114c..f054e17017 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -745,6 +745,9 @@ module ActiveRecord
def from!(value, subquery_name = nil) # :nodoc:
self.from_value = [value, subquery_name]
+ if value.is_a? Relation
+ self.bind_values = value.arel.bind_values + value.bind_values + bind_values
+ end
self
end
@@ -999,7 +1002,6 @@ module ActiveRecord
case opts
when Relation
name ||= 'subquery'
- self.bind_values = opts.bind_values + self.bind_values
opts.arel.as(name.to_s)
else
opts
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 1c48196762..9cef50029b 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -378,7 +378,7 @@ module ActiveRecord
thaw unless restore_state[:frozen?]
@new_record = restore_state[:new_record]
@destroyed = restore_state[:destroyed]
- write_attribute(self.class.primary_key, restore_state[:id])
+ write_attribute(self.class.primary_key, restore_state[:id]) if self.class.primary_key
end
end
end
diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb
index feb1fca500..01ee1234a2 100644
--- a/activerecord/test/cases/attribute_methods_test.rb
+++ b/activerecord/test/cases/attribute_methods_test.rb
@@ -502,7 +502,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
def test_typecast_attribute_from_select_to_false
Topic.create(:title => 'Budget')
# Oracle does not support boolean expressions in SELECT
- if current_adapter?(:OracleAdapter)
+ if current_adapter?(:OracleAdapter, :FbAdapter)
topic = Topic.all.merge!(:select => "topics.*, 0 as is_test").first
else
topic = Topic.all.merge!(:select => "topics.*, 1=2 as is_test").first
@@ -513,7 +513,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
def test_typecast_attribute_from_select_to_true
Topic.create(:title => 'Budget')
# Oracle does not support boolean expressions in SELECT
- if current_adapter?(:OracleAdapter)
+ if current_adapter?(:OracleAdapter, :FbAdapter)
topic = Topic.all.merge!(:select => "topics.*, 1 as is_test").first
else
topic = Topic.all.merge!(:select => "topics.*, 2=2 as is_test").first
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 6acd9aa39f..0debd30e5c 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -88,6 +88,7 @@ class BasicsTest < ActiveRecord::TestCase
'Mysql2Adapter' => '`',
'PostgreSQLAdapter' => '"',
'OracleAdapter' => '"',
+ 'FbAdapter' => '"'
}.fetch(classname) {
raise "need a bad char for #{classname}"
}
@@ -111,7 +112,7 @@ class BasicsTest < ActiveRecord::TestCase
assert_nil Edge.primary_key
end
- unless current_adapter?(:PostgreSQLAdapter, :OracleAdapter, :SQLServerAdapter)
+ unless current_adapter?(:PostgreSQLAdapter, :OracleAdapter, :SQLServerAdapter, :FbAdapter)
def test_limit_with_comma
assert Topic.limit("1,2").to_a
end
diff --git a/activerecord/test/cases/bind_parameter_test.rb b/activerecord/test/cases/bind_parameter_test.rb
index c4634d11e2..66663b3e0e 100644
--- a/activerecord/test/cases/bind_parameter_test.rb
+++ b/activerecord/test/cases/bind_parameter_test.rb
@@ -1,9 +1,11 @@
require 'cases/helper'
require 'models/topic'
+require 'models/author'
+require 'models/post'
module ActiveRecord
class BindParameterTest < ActiveRecord::TestCase
- fixtures :topics
+ fixtures :topics, :authors, :posts
class LogListener
attr_accessor :calls
@@ -30,6 +32,12 @@ module ActiveRecord
end
if ActiveRecord::Base.connection.supports_statement_cache?
+ def test_bind_from_join_in_subquery
+ subquery = Author.joins(:thinking_posts).where(name: 'David')
+ scope = Author.from(subquery, 'authors').where(id: 1)
+ assert_equal 1, scope.count
+ end
+
def test_binds_are_logged
sub = @connection.substitute_at(@pk)
binds = [[@pk, 1]]
diff --git a/activerecord/test/cases/migration/rename_table_test.rb b/activerecord/test/cases/migration/rename_table_test.rb
index c8b3f75e10..a018bac43d 100644
--- a/activerecord/test/cases/migration/rename_table_test.rb
+++ b/activerecord/test/cases/migration/rename_table_test.rb
@@ -39,33 +39,35 @@ module ActiveRecord
end
end
- def test_rename_table
- rename_table :test_models, :octopi
+ unless current_adapter?(:FbAdapter) # Firebird cannot rename tables
+ def test_rename_table
+ rename_table :test_models, :octopi
- connection.execute "INSERT INTO octopi (#{connection.quote_column_name('id')}, #{connection.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')"
+ connection.execute "INSERT INTO octopi (#{connection.quote_column_name('id')}, #{connection.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')"
- assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', connection.select_value("SELECT url FROM octopi WHERE id=1")
- end
+ assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', connection.select_value("SELECT url FROM octopi WHERE id=1")
+ end
- def test_rename_table_with_an_index
- add_index :test_models, :url
+ def test_rename_table_with_an_index
+ add_index :test_models, :url
- rename_table :test_models, :octopi
+ rename_table :test_models, :octopi
- connection.execute "INSERT INTO octopi (#{connection.quote_column_name('id')}, #{connection.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')"
+ connection.execute "INSERT INTO octopi (#{connection.quote_column_name('id')}, #{connection.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')"
- assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', connection.select_value("SELECT url FROM octopi WHERE id=1")
- index = connection.indexes(:octopi).first
- assert index.columns.include?("url")
- assert_equal 'index_octopi_on_url', index.name
- end
+ assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', connection.select_value("SELECT url FROM octopi WHERE id=1")
+ index = connection.indexes(:octopi).first
+ assert index.columns.include?("url")
+ assert_equal 'index_octopi_on_url', index.name
+ end
- def test_rename_table_does_not_rename_custom_named_index
- add_index :test_models, :url, name: 'special_url_idx'
+ def test_rename_table_does_not_rename_custom_named_index
+ add_index :test_models, :url, name: 'special_url_idx'
- rename_table :test_models, :octopi
+ rename_table :test_models, :octopi
- assert_equal ['special_url_idx'], connection.indexes(:octopi).map(&:name)
+ assert_equal ['special_url_idx'], connection.indexes(:octopi).map(&:name)
+ end
end
if current_adapter?(:PostgreSQLAdapter)
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index 57b7346503..b52c66356c 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -272,6 +272,8 @@ class SchemaDumperTest < ActiveRecord::TestCase
# Oracle supports precision up to 38 and it identifies decimals with scale 0 as integers
if current_adapter?(:OracleAdapter)
assert_match %r{t.integer\s+"atoms_in_universe",\s+precision: 38}, output
+ elsif current_adapter?(:FbAdapter)
+ assert_match %r{t.integer\s+"atoms_in_universe",\s+precision: 18}, output
else
assert_match %r{t.decimal\s+"atoms_in_universe",\s+precision: 55}, output
end
diff --git a/activerecord/test/cases/secure_token_test.rb b/activerecord/test/cases/secure_token_test.rb
index 400fce8c6e..dc12b528dc 100644
--- a/activerecord/test/cases/secure_token_test.rb
+++ b/activerecord/test/cases/secure_token_test.rb
@@ -6,13 +6,13 @@ class SecureTokenTest < ActiveRecord::TestCase
@user = User.new
end
- test "assing unique token values" do
+ def test_token_values_are_generated_for_specified_attributes_and_persisted_on_save
@user.save
assert_not_nil @user.token
assert_not_nil @user.auth_token
end
- test "regenerate the secure key for the attribute" do
+ def test_regenerating_the_secure_token
@user.save
old_token = @user.token
old_auth_token = @user.auth_token
@@ -23,15 +23,15 @@ class SecureTokenTest < ActiveRecord::TestCase
assert_not_equal @user.auth_token, old_auth_token
end
- test "raise and exception when with 10 attemps is reached" do
+ def test_raise_after_ten_unsuccessful_attempts_to_generate_a_unique_token
User.stubs(:exists?).returns(*Array.new(10, true))
assert_raises(RuntimeError) do
@user.save
end
end
- test "assing unique token after 9 attemps reached" do
- User.stubs(:exists?).returns(*Array.new(10){ |i| i == 9 ? false : true})
+ def test_return_unique_token_after_nine_unsuccessful_attempts
+ User.stubs(:exists?).returns(*Array.new(10) { |i| i == 9 ? false : true })
@user.save
assert_not_nil @user.token
assert_not_nil @user.auth_token
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 27a7c9212b..d1d8e71c34 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -650,6 +650,27 @@ class TransactionTest < ActiveRecord::TestCase
assert transaction.state.committed?
end
+ def test_transaction_rollback_with_primarykeyless_tables
+ connection = ActiveRecord::Base.connection
+ connection.create_table(:transaction_without_primary_keys, force: true, id: false) do |t|
+ t.integer :thing_id
+ end
+
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = 'transaction_without_primary_keys'
+ after_commit { } # necessary to trigger the has_transactional_callbacks branch
+ end
+
+ assert_no_difference(-> { klass.count }) do
+ ActiveRecord::Base.transaction do
+ klass.create!
+ raise ActiveRecord::Rollback
+ end
+ end
+ ensure
+ connection.execute("DROP TABLE IF EXISTS transaction_without_primary_keys")
+ end
+
private
%w(validation save destroy).each do |filter|
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index e283f7a9cc..21b23d8e0c 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -479,6 +479,8 @@ ActiveRecord::Schema.define do
# Oracle/SQLServer supports precision up to 38
if current_adapter?(:OracleAdapter, :SQLServerAdapter)
t.decimal :atoms_in_universe, precision: 38, scale: 0
+ elsif current_adapter?(:FbAdapter)
+ t.decimal :atoms_in_universe, precision: 18, scale: 0
else
t.decimal :atoms_in_universe, precision: 55, scale: 0
end
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index 52de98ee52..67032a31f5 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -118,9 +118,9 @@
url: initialization.html
description: This guide explains the internals of the Rails initialization process as of Rails 4
-
- name: Constant Autoloading and Reloading
- url: constant_autoloading_and_reloading.html
- description: This guide documents how constant autoloading and reloading work.
+ name: Autoloading and Reloading Constants
+ url: autoloading_and_reloading_constants.html
+ description: This guide documents how autoloading and reloading constants work.
-
name: Active Support Instrumentation
work_in_progress: true