Created
August 13, 2015 12:15
-
-
Save dmitry/73b5baee4957f01bd9d4 to your computer and use it in GitHub Desktop.
Parent controller path through recognize_path
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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