1
0
Fork 0
mirror of https://github.com/heartcombo/devise.git synced 2022-11-09 12:18:31 -05:00
heartcombo--devise/lib/devise/controllers/url_helpers.rb
Griffin Smith 741df732dc Use define_method, not class_eval, for url_helpers
I'm not hugely familiar with ruby internals vis a vis sclass semantics,
but this *probably* serves as a workaround for the MRI thread-safety
bug mentioned in #3505.
Beyond that, and even if this doesn't fix the thread-safety issue, per
[this blog post][1], `define_method` is recommended over `class_eval`
for performance (and, fwiw, readability) reasons anyway.

[1]: http://tenderlovemaking.com/2013/03/03/dynamic_method_definitions.html
2015-05-12 15:05:31 -04:00

67 lines
2.4 KiB
Ruby

module Devise
module Controllers
# Create url helpers to be used with resource/scope configuration. Acts as
# proxies to the generated routes created by devise.
# Resource param can be a string or symbol, a class, or an instance object.
# Example using a :user resource:
#
# new_session_path(:user) => new_user_session_path
# session_path(:user) => user_session_path
# destroy_session_path(:user) => destroy_user_session_path
#
# new_password_path(:user) => new_user_password_path
# password_path(:user) => user_password_path
# edit_password_path(:user) => edit_user_password_path
#
# new_confirmation_path(:user) => new_user_confirmation_path
# confirmation_path(:user) => user_confirmation_path
#
# Those helpers are included by default to ActionController::Base.
#
# In case you want to add such helpers to another class, you can do
# that as long as this new class includes both url_helpers and
# mounted_helpers. Example:
#
# include Rails.application.routes.url_helpers
# include Rails.application.routes.mounted_helpers
#
module UrlHelpers
def self.remove_helpers!
self.instance_methods.map(&:to_s).grep(/_(url|path)$/).each do |method|
remove_method method
end
end
def self.generate_helpers!(routes=nil)
routes ||= begin
mappings = Devise.mappings.values.map(&:used_helpers).flatten.uniq
Devise::URL_HELPERS.slice(*mappings)
end
routes.each do |module_name, actions|
[:path, :url].each do |path_or_url|
actions.each do |action|
action = action ? "#{action}_" : ""
method = :"#{action}#{module_name}_#{path_or_url}"
define_method method do |resource_or_scope, *args|
scope = Devise::Mapping.find_scope!(resource_or_scope)
router_name = Devise.mappings[scope].router_name
context = router_name ? send(router_name) : _devise_route_context
context.send("#{action}#{scope}_#{module_name}_#{path_or_url}", *args)
end
end
end
end
end
generate_helpers!(Devise::URL_HELPERS)
private
def _devise_route_context
@_devise_route_context ||= send(Devise.available_router_name)
end
end
end
end