2013-02-26 12 views
5

Chciałbym utworzyć adres URL za pomocą punktu końcowego i ścieżki lub hosta i ścieżki. Niestety URI.join nie pozwala, aby to zrobić:Utwórz adres URL za pomocą hosta i wielu łańcuchów ścieżek w Railsach

pry(main)> URI.join "https://service.com", "endpoint", "/path" 
=> #<URI::HTTPS:0xa947f14 URL:https://service.com/path> 
pry(main)> URI.join "https://service.com/endpoint", "/path" 
=> #<URI::HTTPS:0xabba56c URL:https://service.com/path> 

i co chcę jest: "https://service.com/endpoint/path". Jak mogłem to zrobić w Ruby/Rails?

EDIT: Jako URI.join ma pewną wadę, jestem skłonny do korzystania File.join:

URI.join("https://service.com", File.join("endpoint", "/path")) 

Co o tym sądzisz?

+1

Check out: http://stackoverflow.com/questions/8900782/how-do-i-safely-join-relative-url-segments –

Odpowiedz

6

URI.join działa tak, jak można by oczekiwać, że znacznik <a> zadziała.

Ty łączenia example.com, endpoint, /path, więc /path zabierze Cię z powrotem do katalogu głównego domeny, zamiast dołączania go.

Musisz zakończyć punkt końcowy za pomocą / i nie rozpoczynać ścieżki od /.

URI.join "https://service.com/", "endpoint/", "path" 
=> #<URI::HTTPS:0x007f8a5b0736d0 URL:https://service.com/endpoint/path> 

Edycja: jak na swoje żądanie w komentarzu poniżej, spróbuj tego:

def join(*args) 
    args.map { |arg| arg.gsub(%r{^/*(.*?)/*$}, '\1') }.join("/") 
end 

Test:

> join "https://service.com/", "endpoint", "path" 
=> "https://service.com/endpoint/path" 
> join "http://example.com//////", "///////a/////////", "b", "c" 
=> "http://example.com/a/b/c" 
+0

Dzięki. Jednak nie chciałbym się przejmować ukośnikami (brak ukośnika, podwójnego ukośnika itd.), Ponieważ 'URI.join (" https://service.com/ "," punkt końcowy "," ścieżka ")' również nie działa poprawnie. Więc cały "URI.join" w moim przypadku jest tak samo użyteczny jak proste połączenie ciągów.Czy wiesz o jakiejś "automatycznej" metodzie łączenia ścieżek w URI bez dbania o ukośniki? – mrzasa

+0

@mrzasa, wypróbuj funkcję, którą dodałem do powyższej odpowiedzi. – Dogbert

+1

@mrzasa, 'URI.join' działa idealnie, gdy podane są wartości, których potrzebuje. Chociaż nie chcesz się tym przejmować, musisz to zrobić, ponieważ to właśnie robią programiści. Musimy zdawać sobie sprawę z wartości wartości, które przekazujemy metodom, aby to, co się dzieje, zwróciło to, czego oczekujemy. Oto coś, o czym warto pomyśleć: "Dwukrotnie pytano mnie:" Módl się, panie Babbage, jeśli włożysz w maszynę niewłaściwe liczby, czy właściwe odpowiedzi wyjdą? " ... Nie jestem w stanie właściwie zrozumieć tego rodzaju pomieszania idei, które mogłyby sprowokować takie pytanie. " -Charles Babbage, fragmenty z życia filozofa –

3

Wygląda kontroli URI.join na obecność znaku slash "/', aby dowiedzieć się, folder na ścieżce URL. Tak więc, jeśli pominąłeś końcowy ukośnik "/" w ścieżce, to nie potraktuje go jako folderu i go pominie. Sprawdź to:

URI.join("https://service.com", 'omitted_part', 'omitted_again', 'end_point_stays').to_s 
# =>"https://service.com/end_point_stays" 

Tu, jeśli staramy się DOŁĄCZ słowami tylko pierwsze i ostatnie params zostać tylko, reszta są pomijane, gdzie pierwszy param jest bezwzględny uri z protokołem & ostatniego param jest punkt końcowy .

Tak więc, jeśli chcesz dołączyć składnik folderu, dodawania końcowy ukośnik w każdym folderze składnika, to tylko on jest uważany za część toru:

URI.join("https://service.com", 'omitted_no_trailing_slash', 'omitted_again', 'stays/', 'end_point_stays').to_s 
# => "https://service.com/stays/end_point_stays" 

Jeszcze jedna ciekawa rzecz do rozważenia jest że jeśli dostarczenie ścieżki w pierwszym parametrze działa następująco:

URI.join("https://service.com/omitted_because_no_trailing_slash", 'end_point_stays').to_s 
# => "https://service.com/end_point_stays" 
URI.join("https://service.com/stays_because_of_trailing_slash/", 'end_point_stays').to_s 
# => "https://service.com/stays_because_of_trailing_slash/end_point_stays" 
URI.join("https://service.com/safe_with_trailing_slash/omitted_because_no_trailing_slash", 'end_point_stays').to_s 
# => "https://service.com/safe_with_trailing_slash/end_point_stays" 
Powiązane problemy