class ActionDispatch::Routing::RouteSet
Monkey Patched Rails’ class ActionDispatch::Routing::RouteSet
.
@author Carlos Alonso
Monkey Patched Rails’ class ActionDispatch::Routing::RouteSet
.
@author Carlos Alonso
Public Instance Methods
Monkey Patched Rails’ method to recognize redirections as well as, for some reason, the original Rails’ method doesn’t.
# File lib/rails_friendly_urls/route_sets/route_set.rb, line 13 def recognize_path(path, environment = {}) method = (environment[:method] || "GET").to_s.upcase path = Journey::Router::Utils.normalize_path(path) unless path =~ %r{://} extras = environment[:extras] || {} begin env = Rack::MockRequest.env_for(path, {:method => method}) rescue URI::InvalidURIError => e raise ActionController::RoutingError, e.message end req = @request_class.new(env) @router.recognize(req) do |route, _matches, params| params = _matches if params.nil? params.merge!(extras) params.merge!(req.parameters.symbolize_keys) params.each do |key, value| if value.is_a?(String) value = value.dup.force_encoding(Encoding::BINARY) params[key] = URI.parser.unescape(value) end end old_params = env[params_key] env[params_key] = (old_params || {}).merge(params) dispatcher = route.app while dispatcher.is_a?(Mapper::Constraints) && dispatcher.matches?(env) do dispatcher = dispatcher.app end if dispatcher.is_a?(Dispatcher) if dispatcher.controller(params, false) dispatcher.prepare_params!(params) return params else raise ActionController::RoutingError, "A route matches #{path.inspect}, but references missing controller: #{params[:controller].camelize}Controller" end elsif dispatcher.is_a?(redirect_class) return { status: 301, path: path_from_dispatcher(dispatcher) } end end raise ActionController::RoutingError, "No route matches #{path.inspect}" end
Monkey Patched Rails’ method: Includes a call to RailsFriendlyUrls::Manager.url_for
when the Rails’ URL Helper is building a url for a path to use the configured SEO Friendly substutition if any.
# File lib/rails_friendly_urls/route_sets/rails3.rb, line 14 def url_for(options = {}) finalize! options = (options || {}).reverse_merge!(default_url_options) handle_positional_args(options) user, password = extract_authentication(options) path_segments = options.delete(:_path_segments) script_name = options.delete(:script_name) path = (script_name.blank? ? _generate_prefix(options) : script_name.chomp('/')).to_s path_options = options.except(*RESERVED_OPTIONS) path_options = yield(path_options) if block_given? path_addition, params = generate(path_options, path_segments || {}) path << path_addition params.merge!(options[:params] || {}) path = RailsFriendlyUrls::Manager.url_for path ActionDispatch::Http::URL.url_for(options.merge!({ :path => path, :params => params, :user => user, :password => password })) end
Private Instance Methods
INTERNAL: Helps deciding which module take the PARAMETERS_KEY constant from. This constant was moved in Rails 4.2 from one to another and using this method here allows us to reuse this file for all Rails 4.x
# File lib/rails_friendly_urls/route_sets/route_set.rb, line 65 def params_key defined?(::ActionDispatch::Http::Parameters::PARAMETERS_KEY) ? ::ActionDispatch::Http::Parameters::PARAMETERS_KEY : ::ActionDispatch::Routing::RouteSet::PARAMETERS_KEY end
INTERNAL: Helps reusing code by obtaining the path from the Rails’ ActionDispatch::Routing::Dispatcher depending on the Rails version running.
@param [ActionDispatch::Routing::Dispatcher] in use. @return [String] the destination path of the redirection.
# File lib/rails_friendly_urls/route_sets/route_set.rb, line 87 def path_from_dispatcher(dispatcher) if Rails::VERSION::MAJOR == 3 dispatcher.block.call({}, nil) else dispatcher.block end end
INTERNAL: Helps reusing code by deciding which class to consider as the redirection depending on the Rails version running.
@returns [ActionDispatch::Routing::Redirect] or [ActionDispatch::Routing::PathRedirect]
# File lib/rails_friendly_urls/route_sets/route_set.rb, line 76 def redirect_class Rails::VERSION::MAJOR == 3 ? Redirect : PathRedirect end