Skip to content

Instantly share code, notes, and snippets.

@dmitry
Created August 13, 2015 12:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmitry/73b5baee4957f01bd9d4 to your computer and use it in GitHub Desktop.
Save dmitry/73b5baee4957f01bd9d4 to your computer and use it in GitHub Desktop.
Parent controller path through recognize_path
class ParentControllerPath
SEGMENT = '/'
attr_reader :path, :found
class << self
def routes
Rails.application.routes
end
end
def initialize(path)
@uri = URI(path)
@path = @uri.path
names = path_to_controller_names
last_name = names.last[:name]
@found = names.reverse[1..-1].find do |v|
v[:name] != last_name
end
end
def generate(actions = nil, options = nil)
([@found[:path]] + Array(actions)).compact.join(ParentControllerPath::SEGMENT).tap do |s|
uri = URI(s)
if @uri.scheme && @uri.host
uri.scheme = @uri.scheme
uri.host = @uri.host
end
if options
if options[:query]
uri.query = "#{Rack::Utils.build_query(options[:query])}"
end
if options[:params]
options[:params].each do |k, v|
uri.send("#{k}=", v)
end
end
end
s.replace(uri.to_s)
end
end
private
def path_to_controller_names
path_segments = @path.split(SEGMENT)
(0..(path_segments.size - 1)).map do |i|
path = path_segments[0..i].join(SEGMENT)
{
path: path,
name: recognized_path(path)[:controller]
}
end
end
def recognized_path(path)
rp = nil
[:get, :post, :put, :patch].find do |method|
begin
rp = self.class.routes.recognize_path(path, method: method)
rescue ActionController::RoutingError
end
end
rp
end
end
# encoding: utf-8
require 'test_helper'
class ParentControllerPathTest < ActiveSupport::TestCase
should 'find correct parent path' do
assert_equal '', ParentControllerPath.new('/bookings').generate
assert_equal '', ParentControllerPath.new('/bookings/1').generate
assert_equal '/accommodations/1/cancellation', ParentControllerPath.new('/accommodations/1/cancellation/paypal/cancel').generate
assert_equal '/accommodations/1/cancellation/success', ParentControllerPath.new('/accommodations/1/cancellation/paypal/cancel').generate('success')
assert_equal '/accommodations/1/cancellation/payment/success', ParentControllerPath.new('/accommodations/1/cancellation/paypal/cancel').generate(['payment', 'success'])
end
should 'add options and params to parent path' do
url = ParentControllerPath.
new('http://9flats.com/accommodations/1/cancellation/paypal/cancel').
generate(nil, query: {a: 2, b: 3}, params: {host: '9flats.ngrok.com'})
assert_equal 'http://9flats.ngrok.com/accommodations/1/cancellation?a=2&b=3', url
url = ParentControllerPath.
new('http://9flats.com/accommodations/1/cancellation/heidelpay/callback').
generate(nil, query: {a: 2, b: 3}, params: {host: '9flats.ngrok.com'})
assert_equal 'http://9flats.ngrok.com/accommodations/1/cancellation?a=2&b=3', url
url = ParentControllerPath.
new('http://9flats.com/accommodations/1/cancellation/heidelpay/callback').
generate(nil, query: {a: 2, b: 3})
assert_equal 'http://9flats.com/accommodations/1/cancellation?a=2&b=3', url
url = ParentControllerPath.
new('http://9flats.com/accommodations/1/cancellation/heidelpay/callback').
generate
assert_equal 'http://9flats.com/accommodations/1/cancellation', url
end
should 'works with locale' do
url = ParentControllerPath.
new('http://9flats.com/de/accommodations/1/cancellation/heidelpay/callback').
generate
assert_equal 'http://9flats.com/de/accommodations/1/cancellation', url
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment