aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb39
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/transaction.rb3
-rw-r--r--guides/source/routing.md2
4 files changed, 31 insertions, 15 deletions
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 947391b725..d869b62398 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -90,17 +90,21 @@ module ActionDispatch
def initialize
@routes = {}
- @helpers = []
+ @helpers = Set.new
@module = Module.new
end
+ def route_defined?(name)
+ @helpers.include? name.to_sym
+ end
+
def helper_names
@helpers.map(&:to_s)
end
def clear!
@helpers.each do |helper|
- @module.remove_possible_method helper
+ @module.send :undef_method, helper
end
@routes.clear
@@ -108,8 +112,12 @@ module ActionDispatch
end
def add(name, route)
- routes[name.to_sym] = route
- define_named_route_methods(name, route)
+ key = name.to_sym
+ if routes.key? key
+ undef_named_route_methods @module, name
+ end
+ routes[key] = route
+ define_named_route_methods(@module, name, route)
end
def get(name)
@@ -253,11 +261,10 @@ module ActionDispatch
#
# foo_url(bar, baz, bang, sort_by: 'baz')
#
- def define_url_helper(route, name, opts, route_key, url_strategy)
+ def define_url_helper(mod, route, name, opts, route_key, url_strategy)
helper = UrlHelper.create(route, opts, route_key, url_strategy)
- @module.remove_possible_method name
- @module.module_eval do
+ mod.module_eval do
define_method(name) do |*args|
options = nil
options = args.pop if args.last.is_a? Hash
@@ -268,9 +275,14 @@ module ActionDispatch
helpers << name
end
- def define_named_route_methods(name, route)
- define_url_helper route, :"#{name}_path", route.defaults, name, PATH
- define_url_helper route, :"#{name}_url", route.defaults, name, FULL
+ def define_named_route_methods(mod, name, route)
+ define_url_helper mod, route, :"#{name}_path", route.defaults, name, PATH
+ define_url_helper mod, route, :"#{name}_url", route.defaults, name, FULL
+ end
+
+ def undef_named_route_methods(mod, name)
+ mod.send :undef_method, :"#{name}_path"
+ mod.send :undef_method, :"#{name}_url"
end
end
@@ -334,6 +346,7 @@ module ActionDispatch
mapper.instance_exec(&block)
end
end
+ private :eval_block
def finalize!
return if @finalized
@@ -400,14 +413,16 @@ module ActionDispatch
def url_options; {}; end
end
+ route_methods = routes.named_routes.module
+
# Make named_routes available in the module singleton
# as well, so one can do:
# Rails.application.routes.url_helpers.posts_path
- extend routes.named_routes.module
+ extend route_methods
# Any class that includes this module will get all
# named routes...
- include routes.named_routes.module
+ include route_methods
# plus a singleton class method called _routes ...
included do
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index f1f998d932..2cf38a9c2d 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -165,7 +165,7 @@ module ActionDispatch
# ROUTES TODO: These assertions should really work in an integration context
def method_missing(selector, *args, &block)
- if defined?(@controller) && @controller && @routes && @routes.named_routes.helpers.include?(selector)
+ if defined?(@controller) && @controller && @routes && @routes.named_routes.route_defined?(selector)
@controller.send(selector, *args, &block)
else
super
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
index 3a266512a9..33cc22425d 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
@@ -72,7 +72,7 @@ module ActiveRecord
end
class TransactionState
- attr_accessor :parent
+ attr_reader :parent
VALID_STATES = Set.new([:committed, :rolledback, nil])
@@ -245,7 +245,6 @@ module ActiveRecord
def perform_commit
@state.set_state(:committed)
- @state.parent = parent.state
connection.release_savepoint(@savepoint_name)
end
end
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 7a7334f25b..af8c1bbcc4 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -645,6 +645,8 @@ match 'photos', to: 'photos#show', via: :all
NOTE: Routing both `GET` and `POST` requests to a single action has security implications. In general, you should avoid routing all verbs to an action unless you have a good reason to.
+NOTE: 'GET' in Rails won't check for CSRF token. You should never write to the database from 'GET' requests, for more information see the [security guide](security.html#csrf-countermeasures) on CSRF countermeasures.
+
### Segment Constraints
You can use the `:constraints` option to enforce a format for a dynamic segment: