aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailer/CHANGELOG.md10
-rw-r--r--actionpack/CHANGELOG.md17
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb8
-rw-r--r--actionpack/test/dispatch/cookies_test.rb12
-rw-r--r--actionview/CHANGELOG.md18
-rw-r--r--activemodel/CHANGELOG.md7
-rw-r--r--activerecord/CHANGELOG.md12
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb5
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb10
-rw-r--r--activerecord/lib/active_record/core.rb2
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb23
-rw-r--r--activerecord/test/cases/store_test.rb24
-rw-r--r--activesupport/CHANGELOG.md7
-rw-r--r--activesupport/lib/active_support/testing/time_helpers.rb57
-rw-r--r--guides/source/4_1_release_notes.md3
-rw-r--r--guides/source/action_controller_overview.md20
-rw-r--r--guides/source/asset_pipeline.md15
-rw-r--r--railties/lib/rails/application/configuration.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt2
-rw-r--r--railties/test/generators/app_generator_test.rb2
20 files changed, 183 insertions, 73 deletions
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md
index c264c710f6..5a61746700 100644
--- a/actionmailer/CHANGELOG.md
+++ b/actionmailer/CHANGELOG.md
@@ -4,7 +4,11 @@
*Andrew White*
* Add the ability to intercept emails before previewing in a similar fashion
- to how emails can be intercepted before delivery, e.g:
+ to how emails can be intercepted before delivery.
+
+ Fixes #13622.
+
+ Example:
class CSSInlineStyler
def self.previewing_email(message)
@@ -14,11 +18,9 @@
ActionMailer::Base.register_preview_interceptor CSSInlineStyler
- Fixes #13622.
-
*Andrew White*
-* Add mailer previews feature based on 37 Signals mail_view gem
+* Add mailer previews feature based on 37 Signals mail_view gem.
*Andrew White*
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index f836b69042..394b1473d3 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,16 +1,17 @@
* Add `:serializer` option for `config.session_store :cookie_store`. This
- changes default serializer when using `:cookie_store` to
- `ActionDispatch::Session::MarshalSerializer` which is wrapper on Marshal.
+ changes default serializer when using `:cookie_store`.
- It is also possible to pass:
+ It is possible to pass:
- * `:json_serializer` which is secure wrapper on JSON using `JSON.parse` and
+ * `:json` which is a secure wrapper on JSON using `JSON.parse` and
`JSON.generate` methods with quirks mode;
- * any other Symbol or String like `:my_custom_serializer` which will be
- camelized and constantized in `ActionDispatch::Session` namespace;
- * serializer object with `load` and `dump` methods defined.
+ * `:marshal` which is a wrapper on Marshal;
+ * serializer class with `load` and `dump` methods defined.
- *Łukasz Sarnacki + Matt Aimonetti*
+ For new apps `:json` option is added by default and :marshal is used
+ when no option is specified.
+
+ *Łukasz Sarnacki*, *Matt Aimonetti*
* Ensure that `request.filtered_parameters` is reset between calls to `process`
in `ActionController::TestCase`.
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index f9f034952e..23d0ecd529 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -466,10 +466,12 @@ module ActionDispatch
end
def serializer
- serializer = @options[:session_serializer] || :marshal_serializer
+ serializer = @options[:session_serializer] || :marshal
case serializer
- when Symbol, String
- ActionDispatch::Session.const_get(serializer.to_s.camelize)
+ when :marshal
+ ActionDispatch::Session::MarshalSerializer
+ when :json
+ ActionDispatch::Session::JsonSerializer
else
serializer
end
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index b19ce905f5..6101acdc25 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -379,7 +379,7 @@ class CookiesTest < ActionController::TestCase
assert_equal 'bar', cookies.encrypted[:foo]
end
- class ActionDispatch::Session::CustomJsonSerializer
+ class CustomJsonSerializer
def self.load(value)
JSON.load(value) + " and loaded"
end
@@ -389,20 +389,14 @@ class CookiesTest < ActionController::TestCase
end
end
- def test_encrypted_cookie_using_custom_json_serializer
- @request.env["action_dispatch.session_serializer"] = :custom_json_serializer
- get :set_encrypted_cookie
- assert_equal 'bar was dumped and loaded', cookies.encrypted[:foo]
- end
-
def test_encrypted_cookie_using_serializer_object
- @request.env["action_dispatch.session_serializer"] = ActionDispatch::Session::CustomJsonSerializer
+ @request.env["action_dispatch.session_serializer"] = CustomJsonSerializer
get :set_encrypted_cookie
assert_equal 'bar was dumped and loaded', cookies.encrypted[:foo]
end
def test_encrypted_cookie_using_json_serializer
- @request.env["action_dispatch.session_serializer"] = :json_serializer
+ @request.env["action_dispatch.session_serializer"] = :json
get :set_encrypted_cookie
cookies = @controller.send :cookies
assert_not_equal 'bar', cookies[:foo]
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index 960f867d99..c370f3df51 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,20 +1,20 @@
* Added `config.action_view.raise_on_missing_translations` to define whether an
error should be raised for missing translations.
- Fixes #13196
+ Fixes #13196.
*Kassio Borges*
* Improved ERB dependency detection. New argument types and formattings for the `render`
calls can be matched.
- Fixes #13074 and #13116
+ Fixes #13074, #13116.
*João Britto*
-* Use `display:none` instead of `display:inline` for hidden fields
+* Use `display:none` instead of `display:inline` for hidden fields.
- Fixes #6403
+ Fixes #6403.
*Gaelian Ditchburn*
@@ -82,11 +82,11 @@
*Yves Senn*
-* Use `set_backtrace` instead of instance variable `@backtrace` in ActionView exceptions
+* Use `set_backtrace` instead of instance variable `@backtrace` in ActionView exceptions.
*Shimpei Makimoto*
-* Fix `simple_format` escapes own output when passing `sanitize: true`
+* Fix `simple_format` escapes own output when passing `sanitize: true`.
*Paul Seidemann*
@@ -104,7 +104,9 @@
*Bogdan Gusiev*
-* Ability to pass block to `select` helper
+* Ability to pass a block to the `select` helper.
+
+ Example:
<%= select(report, "campaign_ids") do %>
<% available_campaigns.each do |c| -%>
@@ -184,7 +186,7 @@
* Fix default rendered format problem when calling `render` without :content_type option.
It should return :html. Fix #11393.
- *Gleb Mazovetskiy* *Oleg* *kennyj*
+ *Gleb Mazovetskiy*, *Oleg*, *kennyj*
* Fix `link_to` with block and url hashes.
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index 0148066bac..6585808fa2 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -18,9 +18,12 @@
*Vince Puzzella*
-* `attribute_changed?` now accepts parameters which check the old and new value of the attribute
+* `attribute_changed?` now accepts a hash to check if the attribute was
+ changed `:from` and/or `:to` a given value.
- `model.name_changed?(from: "Pete", to: "Ringo")`
+ Example:
+
+ model.name_changed?(from: "Pete", to: "Ringo")
*Tejas Dinkar*
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index fe0d7b2b35..7df4720ea5 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,15 @@
+* Active Record objects can now be correctly dumped, loaded and dumped again without issues.
+
+ Previously, if you did `YAML.dump`, `YAML.load` and then `YAML.dump` again
+ in an ActiveRecord model that used serialization it would fail at the last
+ dump due to the fields not being correctly serialized before being dumped
+ to YAML. Now it is possible to dump and load the same object as many times
+ as needed without any issues.
+
+ Fixes #13861.
+
+ *Maurício Linhares*
+
* `find_in_batches` now returns an `Enumerator` when called without a block, so that it
can be chained with other `Enumerable` methods.
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index ccbff8d1ff..9326c9c117 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -278,6 +278,11 @@ module ActiveRecord
}
end
+ # Placeholder so it can be overriden when needed by serialization
+ def attributes_for_coder # :nodoc:
+ attributes
+ end
+
# Returns an <tt>#inspect</tt>-like string for the value of the
# attribute +attr_name+. String attributes are truncated upto 50
# characters, Date and Time attributes are returned in the
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index 3227464032..67abbbc2a0 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -164,6 +164,16 @@ module ActiveRecord
super
end
end
+
+ def attributes_for_coder
+ attribute_names.each_with_object({}) do |name, attrs|
+ attrs[name] = if self.class.serialized_attributes.include?(name)
+ @attributes[name].serialized_value
+ else
+ read_attribute(name)
+ end
+ end
+ end
end
end
end
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 6f02c763fe..6303fe5ee4 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -275,7 +275,7 @@ module ActiveRecord
# Post.new.encode_with(coder)
# coder # => {"attributes" => {"id" => nil, ... }}
def encode_with(coder)
- coder['attributes'] = attributes
+ coder['attributes'] = attributes_for_coder
end
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 88fc47fada..14470f22aa 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -120,6 +120,9 @@ module ActiveRecord
# Will throw an error, but this will work:
#
# User.includes(:posts).where('posts.name = ?', 'example').references(:posts)
+ #
+ # Note that +includes+ works with association names while +references+ needs
+ # the actual table name.
def includes(*args)
check_if_method_has_arguments!(:includes, args)
spawn.includes!(*args)
@@ -163,24 +166,26 @@ module ActiveRecord
self
end
- # Used to indicate that an association is referenced by an SQL string, and should
- # therefore be JOINed in any query rather than loaded separately.
+ # Use to indicate that the given +table_names+ are referenced by an SQL string,
+ # and should therefore be JOINed in any query rather than loaded separately.
+ # This method only works in conjuction with +includes+.
+ # See #includes for more details.
#
# User.includes(:posts).where("posts.name = 'foo'")
# # => Doesn't JOIN the posts table, resulting in an error.
#
# User.includes(:posts).where("posts.name = 'foo'").references(:posts)
# # => Query now knows the string references posts, so adds a JOIN
- def references(*args)
- check_if_method_has_arguments!(:references, args)
- spawn.references!(*args)
+ def references(*table_names)
+ check_if_method_has_arguments!(:references, table_names)
+ spawn.references!(*table_names)
end
- def references!(*args) # :nodoc:
- args.flatten!
- args.map!(&:to_s)
+ def references!(*table_names) # :nodoc:
+ table_names.flatten!
+ table_names.map!(&:to_s)
- self.references_values |= args
+ self.references_values |= table_names
self
end
diff --git a/activerecord/test/cases/store_test.rb b/activerecord/test/cases/store_test.rb
index 6f632b4d8d..978cee9cfb 100644
--- a/activerecord/test/cases/store_test.rb
+++ b/activerecord/test/cases/store_test.rb
@@ -166,4 +166,28 @@ class StoreTest < ActiveRecord::TestCase
test "YAML coder initializes the store when a Nil value is given" do
assert_equal({}, @john.params)
end
+
+ test "attributes_for_coder should return stored fields already serialized" do
+ attributes = {
+ "id" => @john.id,
+ "name"=> @john.name,
+ "settings" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ncolor: black\n",
+ "preferences" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\nremember_login: true\n",
+ "json_data" => "{\"height\":\"tall\"}", "json_data_empty"=>"{\"is_a_good_guy\":true}",
+ "params" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess {}\n",
+ "account_id"=> @john.account_id
+ }
+
+ assert_equal attributes, @john.attributes_for_coder
+ end
+
+ test "dump, load and dump again a model" do
+ dumped = YAML.dump(@john)
+ loaded = YAML.load(dumped)
+ assert_equal @john, loaded
+
+ second_dump = YAML.dump(loaded)
+ assert_equal dumped, second_dump
+ assert_equal @john, YAML.load(second_dump)
+ end
end
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 95bf5601f2..008d71701c 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Remove the deprecation about the `#filter` method.
+
+ Filter objects should now rely on method corresponding to the filter type
+ (e.g. `#before`).
+
+ *Aaron Patterson*
+
* Add `ActiveSupport::JSON::Encoding.time_precision` as a way to configure the
precision of encoded time values:
diff --git a/activesupport/lib/active_support/testing/time_helpers.rb b/activesupport/lib/active_support/testing/time_helpers.rb
index 94230e56ba..0ee6332d6f 100644
--- a/activesupport/lib/active_support/testing/time_helpers.rb
+++ b/activesupport/lib/active_support/testing/time_helpers.rb
@@ -1,7 +1,51 @@
module ActiveSupport
module Testing
+ class SimpleStubs # :nodoc:
+ Stub = Struct.new(:object, :method_name, :original_method)
+
+ def initialize
+ @stubs = {}
+ end
+
+ def stub_object(object, method_name, return_value)
+ key = [object.object_id, method_name]
+
+ if (stub = @stubs[key])
+ unstub_object(stub)
+ end
+
+ new_name = "__simple_stub__#{method_name}"
+
+ @stubs[key] = Stub.new(object, method_name, new_name)
+
+ object.singleton_class.send :alias_method, new_name, method_name
+ object.define_singleton_method(method_name) { return_value }
+ end
+
+ def unstub_all!
+ @stubs.each_value do |stub|
+ unstub_object(stub)
+ end
+ @stubs = {}
+ end
+
+ private
+
+ def unstub_object(stub)
+ singleton_class = stub.object.singleton_class
+ singleton_class.send :undef_method, stub.method_name
+ singleton_class.send :alias_method, stub.method_name, stub.original_method
+ singleton_class.send :undef_method, stub.original_method
+ end
+ end
+
# Containing helpers that helps you test passage of time.
module TimeHelpers
+ def after_teardown #:nodoc:
+ simple_stubs.unstub_all!
+ super
+ end
+
# Change current time to the time in the future or in the past by a given time difference by
# stubbing +Time.now+ and +Date.today+. Note that the stubs are automatically removed
# at the end of each test.
@@ -41,15 +85,20 @@ module ActiveSupport
# end
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
def travel_to(date_or_time, &block)
- Time.stubs now: date_or_time.to_time
- Date.stubs today: date_or_time.to_date
+ simple_stubs.stub_object(Time, :now, date_or_time.to_time)
+ simple_stubs.stub_object(Date, :today, date_or_time.to_date)
if block_given?
block.call
- Time.unstub :now
- Date.unstub :today
+ simple_stubs.unstub_all!
end
end
+
+ private
+
+ def simple_stubs
+ @simple_stubs ||= SimpleStubs.new
+ end
end
end
end
diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md
index 477268f4bc..7399bfb5de 100644
--- a/guides/source/4_1_release_notes.md
+++ b/guides/source/4_1_release_notes.md
@@ -567,6 +567,9 @@ for detailed changes.
* Removed deprecated `assert_present` and `assert_blank` methods, use `assert
object.blank?` and `assert object.present?` instead.
+* Remove deprecated `#filter` method for filter objects, use the corresponding
+ method instead (e.g. `#before` for a before filter).
+
### Deprecations
* Deprecated `Numeric#{ago,until,since,from_now}`, the user is expected to
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index 0234120b45..9eaf03dd82 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -384,20 +384,14 @@ YourApp::Application.config.session_store :cookie_store, key: '_your_app_session
You can pass `:serializer` key to specify serializer for serializing session:
```ruby
-YourApp::Application.config.session_store :cookie_store, key: '_your_app_session', serializer: :json_serializer
+YourApp::Application.config.session_store :cookie_store, key: '_your_app_session', serializer: :json
```
-Default serializer is `:marshal_serializer`. When Symbol or String is passed it
-will look for appropriate class in `ActionDispatch::Session` namespace, so
-passing `:my_custom_serializer` would load
-`ActionDispatch::Session::MyCustomSerializer`.
+The default serializer for new application is `:json`. For compatibility with
+old applications `:marshal` is used when `serializer` option is not specified.
-```ruby
-YourApp::Application.config.session_store :cookie_store, key: '_your_app_session', serializer: :my_custom_serializer
-```
-
-It is also possible to pass serializer object with defined `load` and `dump`
-public methods:
+It is also possible to pass a custom serializer class with `load` and `dump`
+public methods defined:
```ruby
YourApp::Application.config.session_store :cookie_store, key: '_your_app_session', serializer: MyCustomSerializer
@@ -709,7 +703,7 @@ class ApplicationController < ActionController::Base
end
class LoginFilter
- def self.filter(controller)
+ def self.before(controller)
unless controller.send(:logged_in?)
controller.flash[:error] = "You must be logged in to access this section"
controller.redirect_to controller.new_login_url
@@ -718,7 +712,7 @@ class LoginFilter
end
```
-Again, this is not an ideal example for this filter, because it's not run in the scope of the controller but gets the controller passed as an argument. The filter class has a class method `filter` which gets run before or after the action, depending on if it's a before or after filter. Classes used as around filters can also use the same `filter` method, which will get run in the same way. The method must `yield` to execute the action. Alternatively, it can have both a `before` and an `after` method that are run before and after the action.
+Again, this is not an ideal example for this filter, because it's not run in the scope of the controller but gets the controller passed as an argument. The filter class must implement a method with the same name as the filter, so for the `before_action` filter the class must implement a `before` method, and so on. The `around` method must `yield` to execute the action.
Request Forgery Protection
--------------------------
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index 40e0770177..0422dda0d8 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -496,16 +496,11 @@ In this example, `require_self` is used. This puts the CSS contained within the
file (if any) at the precise location of the `require_self` call. If
`require_self` is called more than once, only the last call is respected.
-NOTE. If you want to use multiple Sass files, you should generally use the [Sass
-`@import`
-rule](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import) instead
-of these Sprockets directives. Using Sprockets directives all Sass files exist
-within their own scope, making variables or mixins only available within the
-document they were defined in. You can do file globbing as well using
-`@import "*"`, and `@import "**/*"` to add the whole tree equivalent to how
-`require_tree` works. Check the [sass-rails
-documentation](https://github.com/rails/sass-rails#features) for more info and
-important caveats.
+NOTE. If you want to use multiple Sass files, you should generally use the [Sass `@import` rule](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import)
+instead of these Sprockets directives. Using Sprockets directives all Sass files exist within
+their own scope, making variables or mixins only available within the document they were defined in.
+You can do file globbing as well using `@import "*"`, and `@import "**/*"` to add the whole tree
+equivalent to how `require_tree` works. Check the [sass-rails documentation](https://github.com/rails/sass-rails#features) for more info and important caveats.
You can have as many manifest files as you need. For example, the `admin.css`
and `admin.js` manifest could contain the JS and CSS files that are used for the
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index e902205a13..20e3de32aa 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -109,6 +109,8 @@ module Rails
raise "YAML syntax error occurred while parsing #{paths["config/database"].first}. " \
"Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
"Error: #{e.message}"
+ rescue => e
+ raise e, "Cannot load `Rails.application.database_configuration`:\n#{e.message}", e.backtrace
end
def log_level
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt
index 923d423287..097fcb4bb0 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt
@@ -1,3 +1,3 @@
# Be sure to restart your server when you modify this file.
-Rails.application.config.session_store :cookie_store, key: <%= "'_#{app_name}_session'" %>, serializer: :json_serializer
+Rails.application.config.session_store :cookie_store, key: <%= "'_#{app_name}_session'" %>, serializer: :json
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 8aa306c8e0..700935fd8d 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -433,7 +433,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_new_hash_style
run_generator [destination_root]
assert_file "config/initializers/session_store.rb" do |file|
- assert_match(/config.session_store :cookie_store, key: '_.+_session', serializer: :json_serializer/, file)
+ assert_match(/config.session_store :cookie_store, key: '_.+_session', serializer: :json/, file)
end
end