aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailer/CHANGELOG.md4
-rw-r--r--actionpack/CHANGELOG.md37
-rw-r--r--actionpack/lib/action_controller/log_subscriber.rb5
-rw-r--r--actionpack/lib/action_controller/metal/live.rb1
-rw-r--r--actionpack/lib/action_controller/metal/strong_parameters.rb3
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/tags/base.rb2
-rw-r--r--actionpack/test/template/form_options_helper_test.rb8
-rw-r--r--activemodel/CHANGELOG.md14
-rw-r--r--activerecord/CHANGELOG.md48
-rw-r--r--activerecord/lib/active_record/associations.rb6
-rw-r--r--activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb6
-rw-r--r--activerecord/lib/active_record/core.rb1
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb4
-rw-r--r--activerecord/lib/active_record/migration.rb15
-rw-r--r--activerecord/lib/active_record/persistence.rb2
-rw-r--r--activerecord/test/cases/fixtures_test.rb5
-rw-r--r--activerecord/test/cases/migration_test.rb20
-rw-r--r--activerecord/test/cases/transaction_callbacks_test.rb8
-rw-r--r--activerecord/test/migrations/magic/1_currencies_have_symbols.rb12
-rw-r--r--guides/source/4_0_release_notes.md6
-rw-r--r--guides/source/action_controller_overview.md14
-rw-r--r--guides/source/action_mailer_basics.md15
-rw-r--r--guides/source/active_record_querying.md57
-rw-r--r--guides/source/active_support_instrumentation.md2
-rw-r--r--guides/source/association_basics.md4
-rw-r--r--guides/source/upgrading_ruby_on_rails.md6
-rw-r--r--railties/CHANGELOG.md14
-rw-r--r--railties/lib/rails/application.rb8
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt4
-rw-r--r--railties/test/application/console_test.rb8
-rw-r--r--railties/test/commands/console_test.rb21
32 files changed, 260 insertions, 102 deletions
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md
index 8f74ac0928..487e57be7b 100644
--- a/actionmailer/CHANGELOG.md
+++ b/actionmailer/CHANGELOG.md
@@ -21,7 +21,7 @@
*Olek Janiszewski*
* Eager loading made to use relation's `in_clause_length` instead of host's one.
- Fix #8474
+ Fixes #8474.
*Boris Staal*
@@ -29,7 +29,7 @@
*Nate Berkopec*
* Do not render views when mail() isn't called.
- Fix #7761
+ Fixes #7761.
*Yves Senn*
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 1050626884..157a038b7c 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,5 +1,20 @@
## Rails 4.0.0 (unreleased) ##
+* Fix incorrectly appended square brackets to a multiple select box
+ if an explicit name has been given and it already ends with "[]"
+
+ Before:
+
+ select(:category, [], {}, multiple: true, name: "post[category][]")
+ # => <select name="post[category][][]" ...>
+
+ After:
+
+ select(:category, [], {}, multiple: true, name: "post[category][]")
+ # => <select name="post[category][]" ...>
+
+ *Olek Janiszewski*
+
* Fixed regression when using `assert_template` to verify files sent using
`render file: 'README.md'`.
Fixes #9464.
@@ -237,12 +252,12 @@
Client-IP and Remote-Addr headers, in that order. Document the rationale
for that decision, and describe the options that can be passed to the
RemoteIp middleware to change it.
- Fix #7979
+ Fixes #7979.
*André Arko*, *Steve Klabnik*, *Alexey Gaziev*
* Do not append second slash to `root_url` when using `trailing_slash: true`
- Fix #8700
+ Fixes #8700.
Before:
@@ -270,7 +285,7 @@
* Do not append `charset=` parameter when `head` is called with a
`:content_type` option.
- Fix #8661.
+ Fixes #8661.
*Yves Senn*
@@ -428,7 +443,7 @@
* Render every partial with a new `ActionView::PartialRenderer`. This resolves
issues when rendering nested partials.
- Fix #8197.
+ Fixes #8197.
*Yves Senn*
@@ -436,7 +451,7 @@
of mime types where template text is not html escaped by default. It prevents `Jack & Joe`
from rendering as `Jack &amp; Joe` for the whitelisted mime types. The default whitelist
contains `text/plain`.
- Fix #7976.
+ Fixes #7976.
*Joost Baaij*
@@ -452,7 +467,7 @@
check_box("post", "comment_ids", { multiple: true, index: "foo" }, 1)
# => <input name=\"post[foo][comment_ids][]\" type=\"hidden\" value=\"0\" /><input id=\"post_foo_comment_ids_1\" name=\"post[foo][comment_ids][]\" type=\"checkbox\" value=\"1\" />
- Fix #8108.
+ Fixes #8108.
*Daniel Fox, Grant Hutchins & Trace Wax*
@@ -475,7 +490,7 @@
*Josh Peek*
* `assert_template` can be used to assert on the same template with different locals
- Fix #3675.
+ Fixes #3675.
*Yves Senn*
@@ -486,7 +501,7 @@
* Accept `:remote` as symbolic option for `link_to` helper. *Riley Lynch*
* Warn when the `:locals` option is passed to `assert_template` outside of a view test case
- Fix #3415.
+ Fixes #3415.
*Yves Senn*
@@ -510,12 +525,12 @@
* Rename internal variables on `ActionController::TemplateAssertions` to prevent
naming collisions. `@partials`, `@templates` and `@layouts` are now prefixed with an underscore.
- Fix #7459.
+ Fixes #7459.
*Yves Senn*
* `resource` and `resources` don't modify the passed options hash.
- Fix #7777.
+ Fixes #7777.
*Yves Senn*
@@ -579,7 +594,7 @@
*Guillermo Iguaran*
* Log now displays the correct status code when an exception is raised.
- Fix #7646.
+ Fixes #7646.
*Yves Senn*
diff --git a/actionpack/lib/action_controller/log_subscriber.rb b/actionpack/lib/action_controller/log_subscriber.rb
index 3d274e7dd7..7318c8b7ec 100644
--- a/actionpack/lib/action_controller/log_subscriber.rb
+++ b/actionpack/lib/action_controller/log_subscriber.rb
@@ -48,6 +48,11 @@ module ActionController
info("Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)")
end
+ def unpermitted_parameters(event)
+ unpermitted_keys = event.payload[:keys]
+ debug("Unpermitted parameters: #{unpermitted_keys.join(", ")}")
+ end
+
%w(write_fragment read_fragment exist_fragment?
expire_fragment expire_page write_page).each do |method|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
diff --git a/actionpack/lib/action_controller/metal/live.rb b/actionpack/lib/action_controller/metal/live.rb
index 32e5afa335..9d628c916f 100644
--- a/actionpack/lib/action_controller/metal/live.rb
+++ b/actionpack/lib/action_controller/metal/live.rb
@@ -14,6 +14,7 @@ module ActionController
# response.stream.write "hello world\n"
# sleep 1
# }
+ # ensure
# response.stream.close
# end
# end
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb
index e4dcd3213f..acad8a0799 100644
--- a/actionpack/lib/action_controller/metal/strong_parameters.rb
+++ b/actionpack/lib/action_controller/metal/strong_parameters.rb
@@ -339,7 +339,8 @@ module ActionController
if unpermitted_keys.any?
case self.class.action_on_unpermitted_parameters
when :log
- ActionController::Base.logger.debug "Unpermitted parameters: #{unpermitted_keys.join(", ")}"
+ name = "unpermitted_parameters.action_controller"
+ ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys)
when :raise
raise ActionController::UnpermittedParameters.new(unpermitted_keys)
end
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index 1bad82159a..5afe435459 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -180,7 +180,7 @@ module ActionView
# <title>My Website</title>
# <%= yield :script %>
# </head>
- # <body class="<%= content_for?(:right_col) ? 'one-column' : 'two-column' %>">
+ # <body class="<%= content_for?(:right_col) ? 'two-column' : 'one-column' %>">
# <%= yield %>
# <%= yield :right_col %>
# </body>
diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb
index 3d597079c4..aef1572290 100644
--- a/actionpack/lib/action_view/helpers/tags/base.rb
+++ b/actionpack/lib/action_view/helpers/tags/base.rb
@@ -84,7 +84,7 @@ module ActionView
options["id"] = options.fetch("id"){ tag_id }
end
- options["name"] += "[]" if options["multiple"]
+ options["name"] += "[]" if options["multiple"] && !options["name"].ends_with?("[]")
options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence
end
diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb
index 04cdd068c8..29d63d9653 100644
--- a/actionpack/test/template/form_options_helper_test.rb
+++ b/actionpack/test/template/form_options_helper_test.rb
@@ -575,6 +575,14 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_select_with_multiple_and_with_explicit_name_ending_with_brackets
+ output_buffer = select(:post, :category, [], {include_hidden: false}, multiple: true, name: 'post[category][]')
+ assert_dom_equal(
+ "<select multiple=\"multiple\" id=\"post_category\" name=\"post[category][]\"></select>",
+ output_buffer
+ )
+ end
+
def test_select_with_multiple_and_disabled_to_add_disabled_hidden_input
output_buffer = select(:post, :category, "", {}, :multiple => true, :disabled => true)
assert_dom_equal(
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index 8c54ec3d45..c6d7b0b5d3 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -5,23 +5,25 @@
Example:
- # given User has_secure_password.
+ # Given User has_secure_password.
@user.password = ""
@user.password_confirmation = ""
@user.valid?(:update) # used to be false
+ *Yves Senn*
+
* `validates_confirmation_of` does not override writer methods for
the confirmation attribute if no reader is defined.
Example:
class Blog
- def title=(new_title)
- @title = new_title.downcase
- end
+ def title=(new_title)
+ @title = new_title.downcase
+ end
- # previously this would override the setter above.
- validates_confirmation_of :title
+ # previously this would override the setter above.
+ validates_confirmation_of :title
end
*Yves Senn*
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 63d5bbb9ee..093e9ff6d2 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,8 +1,17 @@
## Rails 4.0.0 (unreleased) ##
-* Fix ActiveRecord `subclass_from_attrs` when `eager_load` is false.
- It cannot find subclass because all classes are loaded automatically
- when it needs.
+* `connection` is deprecated as an instance method.
+ This allows end-users to have a `connection` method on their models
+ without clashing with Active Record internals.
+
+ *Ben Moss*
+
+* When copying migrations, preserve their magic comments and content encoding.
+
+ *OZAWA Sakuro*
+
+* Fix `subclass_from_attrs` when `eager_load` is false. It cannot find
+ subclass because all classes are loaded automatically when it needs.
*Dmitry Vorotilin*
@@ -116,7 +125,7 @@
*Yves Senn*
* Assigning "0.0" to a nullable numeric column does not make it dirty.
- Fix #9034.
+ Fixes #9034.
Example:
@@ -551,17 +560,17 @@
*Marc-André Lafortune*
* Serialized attributes can be serialized in integer columns.
- Fix #8575.
+ Fixes #8575.
*Rafael Mendonça França*
* Keep index names when using `alter_table` with sqlite3.
- Fix #3489.
+ Fixes #3489.
*Yves Senn*
* Add ability for postgresql adapter to disable user triggers in `disable_referential_integrity`.
- Fix #5523.
+ Fixes #5523.
*Gary S. Weaver*
@@ -584,7 +593,7 @@
*Matthew Robertson*
* Recognize migrations placed in directories containing numbers and 'rb'.
- Fix #8492
+ Fixes #8492.
*Yves Senn*
@@ -642,13 +651,13 @@
* Fix performance problem with `primary_key` method in PostgreSQL adapter when having many schemas.
Uses `pg_constraint` table instead of `pg_depend` table which has many records in general.
- Fix #8414
+ Fixes #8414.
*kennyj*
* Do not instantiate intermediate Active Record objects when eager loading.
These records caused `after_find` to run more than expected.
- Fix #3313
+ Fixes #3313.
*Yves Senn*
@@ -669,12 +678,13 @@
* Fix dirty attribute checks for `TimeZoneConversion` with nil and blank
datetime attributes. Setting a nil datetime to a blank string should not
- result in a change being flagged. Fix #8310
+ result in a change being flagged.
+ Fixes #8310.
*Alisdair McDiarmid*
* Prevent mass assignment to the type column of polymorphic associations when using `build`
- Fix #8265
+ Fixes #8265.
*Yves Senn*
@@ -727,7 +737,7 @@
*Bogdan Gusiev*
* `:counter_cache` option for `has_many` associations to support custom named counter caches.
- Fix #7993
+ Fixes #7993.
*Yves Senn*
@@ -751,7 +761,7 @@
*Nikita Afanasenko*
* Use query cache/uncache when using `DATABASE_URL`.
- Fix #6951.
+ Fixes #6951.
*kennyj*
@@ -760,7 +770,7 @@
*Henrik Nyh*
* The `create_table` method raises an `ArgumentError` when the primary key column is redefined.
- Fix #6378
+ Fixes #6378.
*Yves Senn*
@@ -870,7 +880,7 @@
*Alexey Muranov*
* The postgres adapter now supports tables with capital letters.
- Fix #5920
+ Fixes #5920.
*Yves Senn*
@@ -892,7 +902,7 @@
*Francesco Rodriguez*
* Fix `reset_counters` crashing on `has_many :through` associations.
- Fix #7822.
+ Fixes #7822.
*lulalala*
@@ -967,7 +977,7 @@
*Guillermo Iguaran*
* Fix the return of querying with an empty hash.
- Fix #6971.
+ Fixes #6971.
User.where(token: {})
@@ -983,7 +993,7 @@
* Fix creation of through association models when using `collection=[]`
on a `has_many :through` association from an unsaved model.
- Fix #7661.
+ Fixes #7661.
*Ernie Miller*
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 35e4eb19a4..519e9112b8 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1024,7 +1024,7 @@ module ActiveRecord
# [collection<<(object, ...)]
# Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
# Note that this operation instantly fires update sql without waiting for the save or update call on the
- # parent object.
+ # parent object, unless the parent object is a new record.
# [collection.delete(object, ...)]
# Removes one or more objects from the collection by setting their foreign keys to +NULL+.
# Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
@@ -1231,7 +1231,7 @@ module ActiveRecord
# its owner is destroyed:
#
# * <tt>:destroy</tt> causes the associated object to also be destroyed
- # * <tt>:delete</tt> causes the asssociated object to be deleted directly from the database (so callbacks will not execute)
+ # * <tt>:delete</tt> causes the associated object to be deleted directly from the database (so callbacks will not execute)
# * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Callbacks are not executed.
# * <tt>:restrict_with_exception</tt> causes an exception to be raised if there is an associated record
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
@@ -1433,7 +1433,7 @@ module ActiveRecord
# Adds one or more objects to the collection by creating associations in the join table
# (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
# Note that this operation instantly fires update sql without waiting for the save or update call on the
- # parent object.
+ # parent object, unless the parent object is a new record.
# [collection.delete(object, ...)]
# Removes one or more objects from the collection by removing their associations from the join table.
# This does not destroy the objects.
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 93618721bb..bb3e3db379 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
@@ -26,7 +26,7 @@ module ActiveRecord
join_table[reflection.association_foreign_key] => record.id
)
- owner.connection.insert stmt
+ owner.class.connection.insert stmt
end
record
@@ -41,7 +41,7 @@ module ActiveRecord
def delete_records(records, method)
if sql = options[:delete_sql]
records = load_target if records == :all
- records.each { |record| owner.connection.delete(interpolate(sql, record)) }
+ records.each { |record| owner.class.connection.delete(interpolate(sql, record)) }
else
relation = join_table
condition = relation[reflection.foreign_key].eq(owner.id)
@@ -53,7 +53,7 @@ module ActiveRecord
)
end
- owner.connection.delete(relation.where(condition).compile_delete)
+ owner.class.connection.delete(relation.where(condition).compile_delete)
end
end
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 899fe7d7c7..72371be657 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -324,6 +324,7 @@ module ActiveRecord
# also be used to "borrow" the connection to do database work that isn't
# easily done without going straight to SQL.
def connection
+ ActiveSupport::Deprecation.warn("#connection is deprecated in favour of accessing it via the class")
self.class.connection
end
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index 701949e57b..209de78898 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -86,7 +86,7 @@ module ActiveRecord
)
).arel.compile_update(arel_attributes_with_values_for_update(attribute_names))
- affected_rows = connection.update stmt
+ affected_rows = self.class.connection.update stmt
unless affected_rows == 1
raise ActiveRecord::StaleObjectError.new(self, "update")
@@ -117,7 +117,7 @@ module ActiveRecord
if locking_enabled?
column_name = self.class.locking_column
column = self.class.columns_hash[column_name]
- substitute = connection.substitute_at(column, relation.bind_values.length)
+ substitute = self.class.connection.substitute_at(column, relation.bind_values.length)
relation = relation.where(self.class.arel_table[column_name].eq(substitute))
relation.bind_values << [column, self[column_name].to_i]
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 3d71b784e7..5d7762ec3a 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -634,8 +634,17 @@ module ActiveRecord
source_migrations = ActiveRecord::Migrator.migrations(path)
source_migrations.each do |migration|
- source = File.read(migration.filename)
- source = "# This migration comes from #{scope} (originally #{migration.version})\n#{source}"
+ source = File.binread(migration.filename)
+ inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
+ if /\A#.*\b(?:en)?coding:\s*\S+/ =~ source
+ # If we have a magic comment in the original migration,
+ # insert our comment after the first newline(end of the magic comment line)
+ # so the magic keep working.
+ # Note that magic comments must be at the first line(except sh-bang).
+ source[/\n/] = "\n#{inserted_comment}"
+ else
+ source = "#{inserted_comment}#{source}"
+ end
if duplicate = destination_migrations.detect { |m| m.name == migration.name }
if options[:on_skip] && duplicate.scope != scope.to_s
@@ -649,7 +658,7 @@ module ActiveRecord
old_path, migration.filename = migration.filename, new_path
last = migration
- File.open(migration.filename, "w") { |f| f.write source }
+ File.binwrite(migration.filename, source)
copied << migration
options[:on_copy].call(scope, migration, old_path) if options[:on_copy]
destination_migrations << migration
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 347f023793..b25d0601cb 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -410,7 +410,7 @@ module ActiveRecord
def relation_for_destroy
pk = self.class.primary_key
column = self.class.columns_hash[pk]
- substitute = connection.substitute_at(column, 0)
+ substitute = self.class.connection.substitute_at(column, 0)
relation = self.class.unscoped.where(
self.class.arel_table[pk].eq(substitute))
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index b0b29f5f42..8ad40ec3f4 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -477,9 +477,8 @@ class CustomConnectionFixturesTest < ActiveRecord::TestCase
fixtures :courses
self.use_transactional_fixtures = false
- def test_connection
- assert_kind_of Course, courses(:ruby)
- assert_equal Course.connection, courses(:ruby).connection
+ def test_connection_instance_method_deprecation
+ assert_deprecated { courses(:ruby).connection }
end
def test_leaky_destroy
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 6f90500189..f8afb7c591 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -738,6 +738,26 @@ class CopyMigrationsTest < ActiveRecord::TestCase
clear
end
+ def test_copying_migrations_preserving_magic_comments
+ ActiveRecord::Base.timestamped_migrations = false
+ @migrations_path = MIGRATIONS_ROOT + "/valid"
+ @existing_migrations = Dir[@migrations_path + "/*.rb"]
+
+ copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/magic"})
+ assert File.exists?(@migrations_path + "/4_currencies_have_symbols.bukkits.rb")
+ assert_equal [@migrations_path + "/4_currencies_have_symbols.bukkits.rb"], copied.map(&:filename)
+
+ expected = "# coding: ISO-8859-15\n# This migration comes from bukkits (originally 1)"
+ assert_equal expected, IO.readlines(@migrations_path + "/4_currencies_have_symbols.bukkits.rb")[0..1].join.chomp
+
+ files_count = Dir[@migrations_path + "/*.rb"].length
+ copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/magic"})
+ assert_equal files_count, Dir[@migrations_path + "/*.rb"].length
+ assert copied.empty?
+ ensure
+ clear
+ end
+
def test_skipping_migrations
@migrations_path = MIGRATIONS_ROOT + "/valid_with_timestamps"
@existing_migrations = Dir[@migrations_path + "/*.rb"]
diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb
index eb4ffd4498..766a5c0c90 100644
--- a/activerecord/test/cases/transaction_callbacks_test.rb
+++ b/activerecord/test/cases/transaction_callbacks_test.rb
@@ -182,9 +182,9 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
end
def test_call_after_rollback_when_commit_fails
- @first.connection.class.send(:alias_method, :real_method_commit_db_transaction, :commit_db_transaction)
+ @first.class.connection.class.send(:alias_method, :real_method_commit_db_transaction, :commit_db_transaction)
begin
- @first.connection.class.class_eval do
+ @first.class.connection.class.class_eval do
def commit_db_transaction; raise "boom!"; end
end
@@ -194,8 +194,8 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
assert !@first.save rescue nil
assert_equal [:after_rollback], @first.history
ensure
- @first.connection.class.send(:remove_method, :commit_db_transaction)
- @first.connection.class.send(:alias_method, :commit_db_transaction, :real_method_commit_db_transaction)
+ @first.class.connection.class.send(:remove_method, :commit_db_transaction)
+ @first.class.connection.class.send(:alias_method, :commit_db_transaction, :real_method_commit_db_transaction)
end
end
diff --git a/activerecord/test/migrations/magic/1_currencies_have_symbols.rb b/activerecord/test/migrations/magic/1_currencies_have_symbols.rb
new file mode 100644
index 0000000000..c066c068c2
--- /dev/null
+++ b/activerecord/test/migrations/magic/1_currencies_have_symbols.rb
@@ -0,0 +1,12 @@
+# coding: ISO-8859-15
+
+class CurrenciesHaveSymbols < ActiveRecord::Migration
+ def self.up
+ # We use for default currency symbol
+ add_column "currencies", "symbol", :string, :default => ""
+ end
+
+ def self.down
+ remove_column "currencies", "symbol"
+ end
+end
diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md
index 463da488f2..37afb25181 100644
--- a/guides/source/4_0_release_notes.md
+++ b/guides/source/4_0_release_notes.md
@@ -178,12 +178,6 @@ Please refer to the [Changelog](https://github.com/rails/rails/blob/master/activ
If migrating down, the given migration / block is run normally.
See the [Guide on Migration](https://github.com/rails/rails/blob/master/guides/source/migrations.md#reverting-previous-migrations)
-* Adds some metadata columns to `schema_migrations` table.
-
- * `migrated_at`
- * `fingerprint` - an md5 hash of the migration.
- * `name` - the filename minus version and extension.
-
* Adds PostgreSQL array type support. Any datatype can be used to create an array column, with full migration and schema dumper support.
* Add `Relation#load` to explicitly load the record and return `self`.
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index 5861fc3d54..7e0a8a43d4 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -290,6 +290,20 @@ parameters:
params.require(:author).permit(:name, books_attributes: [:title, :id, :_destroy])
```
+Hashes with integer keys are treated differently and you can declare
+the attributes as if they were direct children. You get this kind of
+parameters when you use `accepts_nested_attributes_for` in combination
+with a `has_many` association:
+
+```ruby
+# To whitelist the following data:
+# {"book" => {"title" => "Some Book",
+# "chapters_attributes" => { "1" => {"title" => "First Chapter"},
+# "2" => {"title" => "Second Chapter"}}}}
+
+params.require(:book).permit(:title, chapters_attributes: [:title])
+```
+
#### Outside the Scope of Strong Parameters
The strong parameter API was designed with the most common use cases
diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md
index 8720aae169..31182e9aed 100644
--- a/guides/source/action_mailer_basics.md
+++ b/guides/source/action_mailer_basics.md
@@ -403,7 +403,7 @@ If you wish to override the default delivery options (e.g. SMTP credentials) whi
```ruby
class UserMailer < ActionMailer::Base
- def welcome_email(user,company)
+ def welcome_email(user, company)
@user = user
@url = user_url(@user)
delivery_options = { user_name: company.smtp_user, password: company.smtp_password, address: company.smtp_host }
@@ -412,6 +412,19 @@ class UserMailer < ActionMailer::Base
end
```
+### Sending Emails without Template Rendering
+
+There may be cases in which you want to skip the template rendering step and supply the email body as a string. You can achieve this using the `:body` option.
+In such cases don't forget to add the `:content_type` option. Rails will default to `text/plain` otherwise.
+
+```ruby
+class UserMailer < ActionMailer::Base
+ def welcome_email(user, email_body)
+ mail(to: user.email, body: email_body, content_type: "text/html", subject: "Already rendered!")
+ end
+end
+```
+
Receiving Emails
----------------
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index 0d0813c56a..4a4f814917 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -1196,6 +1196,61 @@ Using a class method is the preferred way to accept arguments for scopes. These
category.posts.created_before(time)
```
+### Merging of scopes
+
+Just like `where` clauses scopes are merged using `AND` conditions.
+
+```ruby
+class User < ActiveRecord::Base
+ scope :active, -> { where state: 'active' }
+ scope :inactive, -> { where state: 'inactive' }
+end
+
+```ruby
+User.active.inactive
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND "users"."state" = 'inactive'
+```
+
+We can mix and match `scope` and `where` conditions and the final sql
+will have all conditions joined with `AND` .
+
+```ruby
+User.active.where(state: 'finished')
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND "users"."state" = 'finished'
+```
+
+If we do want the `last where clause` to win then `Relation#merge` can
+be used .
+
+```ruby
+User.active.merge(User.inactive)
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
+```
+
+One important caveat is that `default_scope` will be overridden by
+`scope` and `where` conditions.
+
+```ruby
+class User < ActiveRecord::Base
+ default_scope { where state: 'pending' }
+ scope :active, -> { where state: 'active' }
+ scope :inactive, -> { where state: 'inactive' }
+end
+
+User.all
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
+
+User.active
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'active'
+
+User.where(state: 'inactive')
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
+```
+
+As you can see above the `default_scope` is being overridden by both
+`scope` and `where` conditions.
+
+
### Applying a default scope
If we wish for a scope to be applied across all queries to the model we can use the
@@ -1399,7 +1454,7 @@ Client.select(:id).map { |c| c.id }
# or
Client.select(:id).map(&:id)
# or
-Client.select(:id).map { |c| [c.id, c.name] }
+Client.select(:id, :name).map { |c| [c.id, c.name] }
```
with
diff --git a/guides/source/active_support_instrumentation.md b/guides/source/active_support_instrumentation.md
index 6b3be69942..d08000eb69 100644
--- a/guides/source/active_support_instrumentation.md
+++ b/guides/source/active_support_instrumentation.md
@@ -450,7 +450,7 @@ ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*a
data # { extra: :information }
```
-You may also subscribe to events matching a regular expresssion. This enables you to subscribe to
+You may also subscribe to events matching a regular expression. This enables you to subscribe to
multiple events at once. Here's you could subscribe to everything from `ActionController`.
```ruby
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md
index cb0a7c8026..65c8154064 100644
--- a/guides/source/association_basics.md
+++ b/guides/source/association_basics.md
@@ -1109,7 +1109,7 @@ end
Controls what happens to the associated object when its owner is destroyed:
* `:destroy` causes the associated object to also be destroyed
-* `:delete` causes the asssociated object to be deleted directly from the database (so callbacks will not execute)
+* `:delete` causes the associated object to be deleted directly from the database (so callbacks will not execute)
* `:nullify` causes the foreign key to be set to `NULL`. Callbacks are not executed.
* `:restrict_with_exception` causes an exception to be raised if there is an associated record
* `:restrict_with_error` causes an error to be added to the owner if there is an associated object
@@ -1463,7 +1463,7 @@ end
Controls what happens to the associated objects when their owner is destroyed:
* `:destroy` causes all the associated objects to also be destroyed
-* `:delete_all` causes all the asssociated objects to be deleted directly from the database (so callbacks will not execute)
+* `:delete_all` causes all the associated objects to be deleted directly from the database (so callbacks will not execute)
* `:nullify` causes the foreign keys to be set to `NULL`. Callbacks are not executed.
* `:restrict_with_exception` causes an exception to be raised if there are any associated records
* `:restrict_with_error` causes an error to be added to the owner if there are any associated objects
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 57945a256b..cb43781f52 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -43,7 +43,7 @@ Rails 4.0 no longer supports loading plugins from `vendor/plugins`. You must rep
* Rails 4.0 has changed how orders get stacked in `ActiveRecord::Relation`. In previous versions of Rails, the new order was applied after the previously defined order. But this is no longer true. Check [Active Record Query guide](active_record_querying.html#ordering) for more information.
-* Rails 4.0 has changed `serialized_attributes` and `attr_readonly` to class methods only. Now you shouldn't use instance methods, it's deprecated. You must change them, e.g. `self.serialized_attributes` to `self.class.serialized_attributes`.
+* Rails 4.0 has changed `serialized_attributes` and `attr_readonly` to class methods only. You shouldn't use instance methods since it's now deprecated. You should change them to use class methods, e.g. `self.serialized_attributes` to `self.class.serialized_attributes`.
* Rails 4.0 has removed `attr_accessible` and `attr_protected` feature in favor of Strong Parameters. You can use the [Protected Attributes gem](https://github.com/rails/protected_attributes) to a smoothly upgrade path.
@@ -65,7 +65,7 @@ Rails 4.0 extracted Active Resource to its own gem. If you still need the featur
### Active Model
-* Rails 4.0 has changed how errors attach with the `ActiveModel::Validations::ConfirmationValidator`. Now when confirmation validations fail the error will be attached to `:#{attribute}_confirmation` instead of `attribute`.
+* Rails 4.0 has changed how errors attach with the `ActiveModel::Validations::ConfirmationValidator`. Now when confirmation validations fail, the error will be attached to `:#{attribute}_confirmation` instead of `attribute`.
* Rails 4.0 has changed `ActiveModel::Serializers::JSON.include_root_in_json` default value to `false`. Now, Active Model Serializers and Active Record objects have the same default behaviour. This means that you can comment or remove the following option in the `config/initializers/wrap_parameters.rb` file:
@@ -128,7 +128,7 @@ get 'こんにちは', controller: 'welcome', action: 'index'
get "/" => "root#index"
```
-* Rails 4.0 has removed ActionDispatch::BestStandardsSupport middleware, !DOCTYPE html already triggers standards mode per http://msdn.microsoft.com/en-us/library/jj676915(v=vs.85).aspx and ChromeFrame header has been moved to `config.action_dispatch.default_headers`
+* Rails 4.0 has removed `ActionDispatch::BestStandardsSupport` middleware, `<!DOCTYPE html>` already triggers standards mode per http://msdn.microsoft.com/en-us/library/jj676915(v=vs.85).aspx and ChromeFrame header has been moved to `config.action_dispatch.default_headers`.
Remember you must also remove any references to the middleware from your application code, for example:
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 4f7cb8254f..420ed476b2 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -39,13 +39,13 @@
*Amparo Luna*
* Fixes database.yml when creating a new rails application with '.'
- Fix #8304
+ Fixes #8304.
*Jeremy W. Rowe*
* Restore Rails::Engine::Railties#engines with deprecation to ensure
compatibility with gems such as Thinking Sphinx
- Fix #8551
+ Fixes #8551.
*Tim Raymond*
@@ -119,7 +119,7 @@
* Environment name can be a start substring of the default environment names
(production, development, test). For example: tes, pro, prod, dev, devel.
- Fix #8628.
+ Fixes #8628.
*Mykola Kyryk*
@@ -129,7 +129,7 @@
* Quote column names in generates fixture files. This prevents
conflicts with reserved YAML keywords such as 'yes' and 'no'
- Fix #8612.
+ Fixes #8612.
*Yves Senn*
@@ -162,19 +162,19 @@
* Add `db` to list of folders included by `rake notes` and `rake notes:custom`. *Antonio Cangiano*
* Engines with a dummy app include the rake tasks of dependencies in the app namespace.
- Fix #8229
+ Fixes #8229.
*Yves Senn*
* Add `sqlserver.yml` template file to satisfy `-d sqlserver` being passed to `rails new`.
- Fix #6882
+ Fixes #6882.
*Robert Nesius*
* Rake test:uncommitted finds git directory in ancestors *Nicolas Despres*
* Add dummy app Rake tasks when `--skip-test-unit` and `--dummy-path` is passed to the plugin generator.
- Fix #8121
+ Fixes #8121.
*Yves Senn*
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 25cc36ff5d..2417bdca21 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -46,10 +46,10 @@ module Rails
# 6) Run config.before_initialize callbacks
# 7) Run Railtie#initializer defined by railties, engines and application.
# One by one, each engine sets up its load paths, routes and runs its config/initializers/* files.
- # 9) Custom Railtie#initializers added by railties, engines and applications are executed
- # 10) Build the middleware stack and run to_prepare callbacks
- # 11) Run config.before_eager_load and eager_load! if eager_load is true
- # 12) Run config.after_initialize callbacks
+ # 8) Custom Railtie#initializers added by railties, engines and applications are executed
+ # 9) Build the middleware stack and run to_prepare callbacks
+ # 10) Run config.before_eager_load and eager_load! if eager_load is true
+ # 11) Run config.after_initialize callbacks
#
class Application < Engine
autoload :Bootstrap, 'rails/application/bootstrap'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index 5669fe6d64..c40eef145f 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
@@ -24,10 +24,10 @@
<%- unless options.skip_sprockets? -%>
# Compress JavaScripts and CSS.
- config.assets.js_compressor = :uglifier
+ config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
- # Whether to fallback to assets pipeline if a precompiled asset is missed.
+ # Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# Generate digests for assets URLs.
diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb
index 592bd73924..af495bb450 100644
--- a/railties/test/application/console_test.rb
+++ b/railties/test/application/console_test.rb
@@ -106,13 +106,13 @@ class FullStackConsoleTest < ActiveSupport::TestCase
teardown_app
end
- def assert_output(expected, timeout = 0.2)
+ def assert_output(expected, timeout = 1)
timeout = Time.now + timeout
output = ""
until output.include?(expected) || Time.now > timeout
if IO.select([@master], [], [], 0.1)
- output << @master.readpartial(100)
+ output << @master.read(1)
end
end
@@ -138,7 +138,7 @@ class FullStackConsoleTest < ActiveSupport::TestCase
in: @slave, out: @slave, err: @slave
)
- assert_output "> ", 5
+ assert_output "> ", 30
pid
end
@@ -157,6 +157,6 @@ class FullStackConsoleTest < ActiveSupport::TestCase
write_prompt "Post.transaction { Post.create; raise }"
write_prompt "Post.count", "=> 0"
ensure
- kill pid
+ kill pid if pid
end
end
diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb
index 6be4a5fe89..3c784b43be 100644
--- a/railties/test/commands/console_test.rb
+++ b/railties/test/commands/console_test.rb
@@ -58,10 +58,7 @@ class Rails::ConsoleTest < ActiveSupport::TestCase
end
def test_console_defaults_to_IRB
- config = mock("config", console: nil)
- app = mock("app", config: config)
- app.expects(:load_console).returns(nil)
-
+ app = build_app(console: nil)
assert_equal IRB, Rails::Console.new(app).console
end
@@ -127,13 +124,15 @@ class Rails::ConsoleTest < ActiveSupport::TestCase
end
def app
- @app ||= begin
- config = mock("config", console: FakeConsole)
- app = mock("app", config: config)
- app.stubs(:sandbox=).returns(nil)
- app.expects(:load_console)
- app
- end
+ @app ||= build_app(console: FakeConsole)
+ end
+
+ def build_app(config)
+ config = mock("config", config)
+ app = mock("app", config: config)
+ app.stubs(:sandbox=).returns(nil)
+ app.expects(:load_console)
+ app
end
def parse_arguments(args)