Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion actionmailer/test/url_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class WelcomeController < ActionController::Base
class UrlTestMailer < ActionMailer::Base
include AppRoutes.url_helpers

default_url_options[:host] = "www.basecamphq.com"
def default_url_options
{ host: "www.basecamphq.com" }
end

configure do |c|
c.assets_dir = "" # To get the tests to pass
Expand Down
43 changes: 40 additions & 3 deletions actionpack/lib/action_dispatch/routing/url_for.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,56 @@ module Routing
# User.find(1).base_uri # => "/users/1"
#
module UrlFor
class DefaultUrlOptionsProxy # :nodoc:
def initialize(owner)
@owner = owner
end

def to_hash
@owner.default_url_options_hash
end

def method_missing(name, *args)
return super unless @owner.default_url_options_hash.respond_to?(name)

@owner.default_url_options_hash.public_send(name, *args)
rescue FrozenError
trigger_deprecation

@owner.default_url_options_hash = @owner.default_url_options_hash.dup
@owner.default_url_options_hash.public_send(name, *args)
end

def respond_to_missing?(name, _)
@owner.respond_to?(name) || super
end

private

def trigger_deprecation
ActionController.deprecator.warn(<<~MSG.squish)
Mutating the `default_url_options` is deprecated and will raise a FrozenError in the next
Rails release. Mutating the `default_url_options` can be a source of hard to debug issues.

Instead, implement `def default_url_options` in your class or controller.
MSG
end
end

extend ActiveSupport::Concern
include PolymorphicRoutes

included do
unless method_defined?(:default_url_options)
# Including in a class uses an inheritable hash. Modules get a plain hash.
if respond_to?(:class_attribute)
class_attribute :default_url_options
class_attribute :default_url_options, :default_url_options_hash
else
mattr_writer :default_url_options
mattr_writer :default_url_options, :default_url_options_hash
end

self.default_url_options = {}
self.default_url_options_hash = {}.freeze
self.default_url_options = DefaultUrlOptionsProxy.new(self).freeze
end

include(*_url_for_modules) if respond_to?(:_url_for_modules)
Expand Down
3 changes: 2 additions & 1 deletion actionpack/lib/action_dispatch/testing/integration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ def initialize(app)
end

def url_options
@url_options ||= default_url_options.dup.tap do |url_options|
@url_options ||= begin
url_options = {}.merge(default_url_options)
url_options.reverse_merge!(controller.url_options) if controller.respond_to?(:url_options)

if @app.respond_to?(:routes)
Expand Down
8 changes: 5 additions & 3 deletions actionview/test/activerecord/polymorphic_routes_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ class PolymorphicRoutesTest < ActionController::TestCase
Routes.draw { }
include Routes.url_helpers

default_url_options[:host] = "example.com"
def default_url_options
{ host: "example.com" }
end

def setup
super
Expand All @@ -83,7 +85,7 @@ def setup
end

def assert_url(url, args)
host = self.class.default_url_options[:host]
host = default_url_options[:host]

assert_equal url.delete_prefix("http://#{host}"), polymorphic_path(args)
assert_equal url, polymorphic_url(args)
Expand Down Expand Up @@ -741,7 +743,7 @@ class PolymorphicPathRoutesTest < PolymorphicRoutesTest
attr_accessor :controller

def assert_url(url, args)
host = self.class.default_url_options[:host]
host = default_url_options[:host]

assert_equal url.delete_prefix("http://#{host}"), url_for(args)
end
Expand Down
Loading