diff options
-rw-r--r-- | Gemfile | 3 | ||||
-rw-r--r-- | Gemfile.lock | 12 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/base.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/cookies.rb | 10 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/url_for.rb | 22 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/form_options_helper.rb | 12 | ||||
-rw-r--r-- | activejob/lib/active_job/arguments.rb | 21 | ||||
-rw-r--r-- | activejob/test/cases/argument_serialization_test.rb | 7 | ||||
-rw-r--r-- | activerecord/lib/active_record/fixtures.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/calculations.rb | 5 | ||||
-rw-r--r-- | activerecord/test/cases/enum_test.rb | 6 | ||||
-rw-r--r-- | activerecord/test/fixtures/books.yml | 5 | ||||
-rw-r--r-- | guides/source/action_mailer_basics.md | 18 | ||||
-rw-r--r-- | guides/source/action_view_overview.md | 12 |
14 files changed, 98 insertions, 45 deletions
@@ -5,6 +5,9 @@ gemspec # We need a newish Rake since Active Job sets its test tasks' descriptions. gem 'rake', '>= 10.3' +# Active Job depends on the URI::GID::MissingModelIDError, which isn't released yet. +gem 'globalid', github: 'rails/globalid' + # This needs to be with require false as it is # loaded after loading the test library to # ensure correct loading order diff --git a/Gemfile.lock b/Gemfile.lock index 2140881170..960a77af92 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,6 +26,13 @@ GIT arel (7.0.0.alpha) GIT + remote: git://github.com/rails/globalid.git + revision: 4df66fb9e9f0c832d29119aa8bc30be55a614b71 + specs: + globalid (0.3.5) + activesupport (>= 4.1.0) + +GIT remote: git://github.com/rails/jquery-rails.git revision: 272abdd319bb3381b23182b928b25320590096b0 branch: master @@ -138,8 +145,6 @@ GEM delayed_job (>= 3.0, < 4.1) erubis (2.7.0) execjs (2.3.0) - globalid (0.3.3) - activesupport (>= 4.1.0) hitimes (1.2.2) hitimes (1.2.2-x86-mingw32) i18n (0.7.0) @@ -272,6 +277,7 @@ DEPENDENCIES dalli (>= 2.2.1) delayed_job delayed_job_active_record + globalid! jquery-rails! json kindlerb (= 0.1.1) @@ -308,4 +314,4 @@ DEPENDENCIES w3c_validators BUNDLED WITH - 1.10.4 + 1.10.5 diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 96d701dba5..ebd02bd9a1 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -148,9 +148,6 @@ module AbstractController # # ==== Parameters # * <tt>action_name</tt> - The name of an action to be tested - # - # ==== Returns - # * <tt>TrueClass</tt>, <tt>FalseClass</tt> def available_action?(action_name) _find_action_name(action_name).present? end @@ -171,9 +168,6 @@ module AbstractController # ==== Parameters # * <tt>name</tt> - The name of an action to be tested # - # ==== Returns - # * <tt>TrueClass</tt>, <tt>FalseClass</tt> - # # :api: private def action_method?(name) self.class.action_methods.include?(name) diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index dd1f140051..9a1e2bd45c 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -8,7 +8,7 @@ require 'active_support/json' module ActionDispatch class Request < Rack::Request def cookie_jar - env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(self) + env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(env, host, ssl?, cookies) end end @@ -228,16 +228,12 @@ module ActionDispatch } end - def self.build(request) - env = request.env + def self.build(env, host, secure, cookies) key_generator = env[GENERATOR_KEY] options = options_for_env env - host = request.host - secure = request.ssl? - new(key_generator, host, secure, options).tap do |hash| - hash.update(request.cookies) + hash.update(cookies) end end diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index eb554ec383..8379d089df 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -52,9 +52,11 @@ module ActionDispatch # argument. # # For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for. - # So within mailers, you only have to type 'url_for' instead of 'ActionController::UrlFor#url_for' - # in full. However, mailers don't have hostname information, and that's why you'll still - # have to specify the <tt>:host</tt> argument when generating URLs in mailers. + # So within mailers, you only have to type +url_for+ instead of 'ActionController::UrlFor#url_for' + # in full. However, mailers don't have hostname information, and you still have to provide + # the +:host+ argument or set the default host that will be used in all mailers using the + # configuration option +config.action_mailer.default_url_options+. For more information on + # url_for in mailers read the ActionMailer#Base documentation. # # # == URL generation for named routes @@ -147,6 +149,20 @@ module ActionDispatch # # => 'http://somehost.org/myapp/tasks/testing' # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp", only_path: true # # => '/myapp/tasks/testing' + # + # Missing routes keys may be filled in from the current request's parameters + # (e.g. +:controller+, +:action+, +:id+ and any other parameters that are + # placed in the path). Given that the current action has been reached + # through `GET /users/1`: + # + # url_for(only_path: true) # => '/users/1' + # url_for(only_path: true, action: 'edit') # => '/users/1/edit' + # url_for(only_path: true, action: 'edit', id: 2) # => '/users/2/edit' + # + # Notice that no +:id+ parameter was provided to the first +url_for+ call + # and the helper used the one from the route's path. Any path parameter + # implicitly used by +url_for+ can always be overwritten like shown on the + # last +url_for+ calls. def url_for(options = nil) case options when nil diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb index 1b7b188d65..8e729b3c39 100644 --- a/actionview/lib/action_view/helpers/form_options_helper.rb +++ b/actionview/lib/action_view/helpers/form_options_helper.rb @@ -35,8 +35,8 @@ module ActionView # <select name="post[person_id]" id="post_person_id"> # <option value="">None</option> # <option value="1">David</option> - # <option value="2" selected="selected">Sam</option> - # <option value="3">Tobias</option> + # <option value="2" selected="selected">Eileen</option> + # <option value="3">Rafael</option> # </select> # # * <tt>:prompt</tt> - set to true or a prompt string. When the select element doesn't have a value yet, this prepends an option with a generic prompt -- "Please select" -- or the given prompt string. @@ -48,8 +48,8 @@ module ActionView # <select name="post[person_id]" id="post_person_id"> # <option value="">Select Person</option> # <option value="1">David</option> - # <option value="2">Sam</option> - # <option value="3">Tobias</option> + # <option value="2">Eileen</option> + # <option value="3">Rafael</option> # </select> # # * <tt>:index</tt> - like the other form helpers, +select+ can accept an <tt>:index</tt> option to manually set the ID used in the resulting output. Unlike other helpers, +select+ expects this @@ -112,8 +112,8 @@ module ActionView # <select name="post[person_id]" id="post_person_id"> # <option value=""></option> # <option value="1" selected="selected">David</option> - # <option value="2">Sam</option> - # <option value="3">Tobias</option> + # <option value="2">Eileen</option> + # <option value="3">Rafael</option> # </select> # # assuming the associated person has ID 1. diff --git a/activejob/lib/active_job/arguments.rb b/activejob/lib/active_job/arguments.rb index cdb37879b6..8e462bfe5d 100644 --- a/activejob/lib/active_job/arguments.rb +++ b/activejob/lib/active_job/arguments.rb @@ -16,13 +16,13 @@ module ActiveJob end end - # Raised when an unsupported argument type is being set as job argument. We + # Raised when an unsupported argument type is set as a job argument. We # currently support NilClass, Fixnum, Float, String, TrueClass, FalseClass, - # Bignum and object that can be represented as GlobalIDs (ex: Active Record). - # Also raised if you set the key for a Hash something else than a string or - # a symbol. - class SerializationError < ArgumentError - end + # Bignum and objects that can be represented as GlobalIDs (ex: Active Record). + # Raised if you set the key for a Hash something else than a string or + # a symbol. Also raised when trying to serialize an object which can't be + # identified with a Global ID - such as an unpersisted Active Record model. + class SerializationError < ArgumentError; end module Arguments extend self @@ -59,7 +59,7 @@ module ActiveJob when *TYPE_WHITELIST argument when GlobalID::Identification - { GLOBALID_KEY => argument.to_global_id.to_s } + convert_to_global_id_hash(argument) when Array argument.map { |arg| serialize_argument(arg) } when ActiveSupport::HashWithIndifferentAccess @@ -147,5 +147,12 @@ module ActiveJob end end end + + def convert_to_global_id_hash(argument) + { GLOBALID_KEY => argument.to_global_id.to_s } + rescue URI::GID::MissingModelIdError + raise SerializationError, "Unable to serialize #{argument.class} " \ + "without an id. (Maybe you forgot to call save?)" + end end end diff --git a/activejob/test/cases/argument_serialization_test.rb b/activejob/test/cases/argument_serialization_test.rb index 8b9b62190f..933972a52b 100644 --- a/activejob/test/cases/argument_serialization_test.rb +++ b/activejob/test/cases/argument_serialization_test.rb @@ -88,6 +88,13 @@ class ArgumentSerializationTest < ActiveSupport::TestCase assert_equal "Job with argument: 2", JobBuffer.last_value end + test 'raises a friendly SerializationError for records without ids' do + err = assert_raises ActiveJob::SerializationError do + ActiveJob::Arguments.serialize [Person.new(nil)] + end + assert_match 'Unable to serialize Person without an id.', err.message + end + private def assert_arguments_unchanged(*args) assert_arguments_roundtrip args diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index b01444a090..d062dd9e34 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -645,7 +645,9 @@ module ActiveRecord # Resolve enums model_class.defined_enums.each do |name, values| - row[name] = values.fetch(row[name], row[name]) + if row.include?(name) + row[name] = values.fetch(row[name], row[name]) + end end # If STI is used, find the correct subclass for association reflection diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index df72ba7e9c..0f6015fa93 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -139,7 +139,7 @@ module ActiveRecord # # SELECT people.id, people.name FROM people # # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']] # - # Person.uniq.pluck(:role) + # Person.distinct.pluck(:role) # # SELECT DISTINCT role FROM people # # => ['admin', 'member', 'guest'] # @@ -195,7 +195,8 @@ module ActiveRecord def perform_calculation(operation, column_name) operation = operation.to_s.downcase - # If #count is used with #distinct / #uniq it is considered distinct. (eg. relation.distinct.count) + # If #count is used with #distinct (i.e. `relation.distinct.count`) it is + # considered distinct. distinct = self.distinct_value if operation == "count" diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index 769b171717..ba23049a92 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -405,4 +405,10 @@ class EnumTest < ActiveRecord::TestCase assert_not @book.in_spanish? assert_not @book.in_french? end + + test "uses default status when no status is provided in fixtures" do + book = books(:tlg) + assert book.proposed?, "expected fixture to default to proposed status" + assert book.in_english?, "expected fixture to default to english language" + end end diff --git a/activerecord/test/fixtures/books.yml b/activerecord/test/fixtures/books.yml index 93cfabd61c..a304fba399 100644 --- a/activerecord/test/fixtures/books.yml +++ b/activerecord/test/fixtures/books.yml @@ -24,3 +24,8 @@ ddd: name: "Domain-Driven Design" format: "hardcover" status: 2 + +tlg: + author_id: 1 + id: 4 + name: "Thoughtleadering" diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md index 6f159b2fc4..c31b50fcfc 100644 --- a/guides/source/action_mailer_basics.md +++ b/guides/source/action_mailer_basics.md @@ -533,6 +533,24 @@ url helper. NOTE: non-`GET` links require [jQuery UJS](https://github.com/rails/jquery-ujs) and won't work in mailer templates. They will result in normal `GET` requests. +### Adding images in Action Mailer Views + +Unlike controllers, the mailer instance doesn't have any context about the +incoming request so you'll need to provide the `:asset_host` parameter yourself. + +As the `:asset_host` usually is consistent across the application you can +configure it globally in config/application.rb: + +```ruby +config.action_mailer.asset_host = 'http://example.com' +``` + +Now you can display an image inside your email. + +```ruby +<%= image_tag 'image.jpg' %> +``` + ### Sending Multipart Emails Action Mailer will automatically send multipart emails if you have different diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md index 3c1c3c7873..98c6cbd540 100644 --- a/guides/source/action_view_overview.md +++ b/guides/source/action_view_overview.md @@ -1059,14 +1059,6 @@ If `@article.author_ids` is [1], this would return: <input name="article[author_ids][]" type="hidden" value="" /> ``` -#### country_options_for_select - -Returns a string of option tags for pretty much any country in the world. - -#### country_select - -Returns select and option tags for the given object and method, using country_options_for_select to generate the list of option tags. - #### option_groups_from_collection_for_select Returns a string of `option` tags, like `options_from_collection_for_select`, but groups them by `optgroup` tags based on the object relationships of the arguments. @@ -1153,8 +1145,8 @@ If `@article.person_id` is 1, this would become: <select name="article[person_id]"> <option value=""></option> <option value="1" selected="selected">David</option> - <option value="2">Sam</option> - <option value="3">Tobias</option> + <option value="2">Eileen</option> + <option value="3">Rafael</option> </select> ``` |