Как получить текущий абсолютный URL в Ruby on Rails?


Ответы:


1443

Для Rails 3.2 или Rails 4+

Вы должны использовать, request.original_urlчтобы получить текущий URL.

Этот метод описан в методе original_url , но если вам интересно, реализация такова:

def original_url
  base_url + original_fullpath
end

Для Rails 3:

Вы можете написать "#{request.protocol}#{request.host_with_port}#{request.fullpath}", так request.urlкак теперь устарела.


Для Rails 2:

Вы можете написать request.urlвместо request.request_uri. Это объединяет протокол (обычно http: //) с хостом и request_uri, чтобы дать вам полный адрес.


31
как указывали другие пользователи: ПРЕДУПРЕЖДЕНИЕ ОБ УСТРОЙСТВЕ: Использование #request_uri не рекомендуется. Вместо этого используйте полный путь
giladbu

9
@giladbu fullpathНЕ включает протокол / домен / порт! Это не абсолютный URL!
Алан Х.

37
"http://#{request.host+request.fullpath}"будет работать или нет, (если порт важен)"http://#{request.host}:#{request.port+request.fullpath}"
Nilloc

7
если порт важен, этот работает правильно: "http://#{request.host}:#{request.port}#{request.fullpath}"
Sucrenoir

3
Можете ли вы указать ссылку на претензию, которая request.urlустарела? Предложенное решение - просто длинный способ сказать, что request.urlуже делает; реализация это просто протокол + host_with_port + fullpath ( github.com/rails/rails/blob/… )
mhartl

134

Я думаю, что метод Ruby on Rails 3.0 сейчас request.fullpath.


13
полный путь не включает домен
lulalala

Я рад, что это было предоставлено, поскольку я действительно искал, как не включать домен.
Джейк

121

Вы могли бы использовать url_for(only_path: false)


В моем (немного особом случае) это было почти то, что я хотел. Я просто изменил параметр на true и получил URL для текущей страницы, без параметров. Спасибо :)
Спиралис

@ Давида нет в View это не так. Но это не должно использоваться там в любом случае =)
Любен Тодоров

В моем случае я хотел изменить имя хоста, но оставил все остальное. Я обнаружил, что url_for (хост: «www.newdomain.com») работал для меня лучше всего как решение проблемы. ИМО, это более надежное решение, поскольку оно одинаково для всех версий рельсов.
PeppyHeppy

1
К вашему сведению Это не будет работать, если у вас есть несколько путей для одного и того же ресурса.
thekingoftruth

68

ПРЕДУПРЕЖДЕНИЕ О УСТАРЕВАНИИ : Использование #request_uri устарело . Вместо этого используйте полный путь.


4
См. Примечания к ответу stackoverflow.com/a/2165727/166279 , полный путь не включает домен.
Nilloc

эта строка пришла прямо из журнала во время записи при использовании, request.uriи на это уже несколько раз указывалось в этом вопросе, но ... хорошо, спасибо
ecoologic

1
@ManishShrivastava: забавно, несмотря на все «оригинальные» усилия, которые я приложил, отвечая на более сложные вопросы, эта копия и вставка дали мне наивысший балл, ну ... лучше, чем ничего
ecoologic


52

Вы можете добавить этот метод current_url в ApplicationController, чтобы вернуть текущий URL и разрешить объединение других параметров

# https://x.com/y/1?page=1 
# + current_url( :page => 3 )
# = https://x.com/y/1?page=3
def current_url(overwrite={})
    url_for :only_path => false, :params => params.merge(overwrite)
end

Пример использования:

current_url --> http://...
current_url(:page=>4) --> http://...&page=4

1
Похоже, это не определено в Rails 3.1.
Алан Х.

1
Вы могли бы сделать это таким образомurl_for params.merge(:format => "PDF", :only_path => false)
montrealmike

2
Кроме того, если вы находитесь в link_toвы можете просто использовать params.mergeи пропустить в url_forцелом
montrealmike

36

Для Ruby on Rails 3:

request.url
request.host_with_port

Я запустил сеанс отладчика и запросил объект запроса:

request.public_methods


28

Мне нужен был URL приложения, но с подкаталогом. Я использовал:

root_url(:only_path => false)

27
 url_for(params)

И вы можете легко добавить новый параметр:

url_for(params.merge(:tag => "lol"))

5
Это гораздо более элегантно (хотя и менее детально), чем утвержденный ответ.
Оливье Лакан

16

Я думаю, что request.domain будет работать, но что, если вы находитесь в подкаталоге вроде blah.blah.com? Нечто подобное может сработать:

<%= request.env["HTTP_HOST"] + page = "/" + request.path_parameters['controller'] + "/" + request.path_parameters['action'] %>

Измените параметры в зависимости от вашей структуры пути.

Надеюсь, это поможет!


8
Да, ответ Хайме намного лучше, но если вы хотите быть действительно неэффективным, вы можете сделать это по-моему.
Джеймс М

14

Похоже, request_uriне рекомендуется в Ruby on Rails 3.

Using #request_uri is deprecated. Use fullpath instead.

13

Используя Ruby 1.9.3-p194 и Ruby on Rails 3.2.6:

Если request.fullpath у вас не работает, попробуйте request.env ["HTTP_REFERER"]

Вот моя история ниже.

У меня возникла аналогичная проблема с определением текущего URL-адреса (который отображается в адресной строке пользователя в ее браузере) для кумулятивных страниц, которые объединяют информацию, например, с разных контроллеров http://localhost:3002/users/1/history/issues .

Пользователь может переключаться на разные списки типов проблем. Все эти списки загружаются через Ajax с разных контроллеров / частичных (без перезагрузки).

Проблема заключалась в том, чтобы задать правильный путь для кнопки «Назад» в каждом элементе списка, чтобы кнопка «Назад» могла корректно работать как на своей собственной странице, так и в совокупной истории страниц. .

В случае, если я использую request.fullpath , он возвращает путь последнего запроса JavaScript, который определенно не является URL-адресом, который я ищу.

Поэтому я использовал request.env ["HTTP_REFERER"], в котором хранится URL-адрес последнего загруженного запроса.

Вот выдержка из частичного, чтобы принять решение

- if request.env["HTTP_REFERER"].to_s.scan("history").length > 0
  - back_url = user_history_issue_path(@user, list: "needed_type")
- else
  - back_url = user_needed_type_issue_path(@user)
- remote ||= false
=link_to t("static.back"), back_url, :remote => remote

Да, fullpath возвращает вам запрошенный URL-адрес, а не URL-адрес, с которого вы пришли , и это тоже то, что мне было нужно. Спасибо за это!
Спенсер Ратбун,

2
Прекрасно работает, как раз то, что мне нужно. Это должно быть в отдельном вопросе и ответе все же. Вроде сложно найти здесь. : /
DDDD

12

Это работает для Ruby on Rails 3.0 и должно поддерживаться большинством версий Ruby on Rails:

request.env['REQUEST_URI']

11

К сожалению, ни одно из предложений в этой ветке мне не помогло, кроме одного, где кто-то сказал, что он использовал отладчик, чтобы найти то, что он искал.

Я создал несколько пользовательских страниц ошибок вместо стандартных 404 и 500, но request.urlзакончил /404вместо ожидаемых/non-existing-mumbo-jumbo .

Что мне нужно было использовать

request.original_url

9

Если под относительным вы подразумеваете просто без домена, то посмотрите в request.domain.



8

Вы можете использовать метод ruby:

:root_url

который получит полный путь с базовым URL:

localhost:3000/bla

Это единственное решение, которое работает в сериализаторах, использующих active_model_serializer в Rails 4.
Крис Хайра

Подскажите, пожалуйста, как я могу ограничить передаваемые параметры абсолютным URL-адресом, когда я использую что-то подобное, :root_urlчтобы получить абсолютный URL? Предположим, я использую что-то вроде этого some_method(:products_brand_url, brand: brand, entity_name: "brand")и some_methodопределяется как `def some_method (route, opts = {}) end` Я не хочу, чтобы мой маршрут выглядел как - http://localhost:3000/brands/brand_name?&entity_name="brand". Я хочу, чтобы маршрут выглядел так http://localhost:3000/brands/brand_name. Я просто хочу, entity_nameчтобы он был частью хэша opts, а не в качестве параметра к абсолютному URL.
бодхисаттва

Конечно, нет никакого вызываемого метода Rubyroot_url .
smileart


6

Вы можете использовать любой для рельсов 3.2:

request.original_url
or
request.env["HTTP_REFERER"]
or
request.env['REQUEST_URI']

Я думаю, что это будет работать везде

"#{request.protocol}#{request.host}:#{request.port}#{request.fullpath}"

6

Rails 4.0

вы можете использовать request.original_url, вывод будет как приведенный ниже пример

get "/articles?page=2"

request.original_url # => "http://www.example.com/articles?page=2"

4

Для Rails 3.2 или Rails 4 Просто получите таким образом «request.original_url» Ссылка: Оригинальный метод URL

Для Rails 3 Поскольку request.url устарел. Мы можем получить абсолютный путь путем объединения

"#{request.protocol}#{request.host_with_port}#{request.fullpath}"

Для Rails 2

request.url

3

если вы хотите быть конкретным, то есть знаете, какой путь вам нужен:

link_to current_path(@resource, :only_path => false), current_path(@resource)



3

Получить URL запроса без каких-либо параметров запроса.

def current_url_without_parameters
  request.base_url + request.path
end

3

Вы можете использовать

request.original_url 

или

"#{request.protocol}#{request.host_with_port}" 

чтобы получить текущий URL.



1

Вы можете установить переменную на. URI.parse(current_url)Я не вижу здесь этого предложения, и оно работает для меня.


0

Чтобы получить абсолютный URL, который означает, что from the rootон может отображаться следующим образом

<%= link_to 'Edit', edit_user_url(user) %>

Помощник users_url генерирует URL, который включает протокол и имя хоста. Помощник users_path генерирует только часть пути.

users_url: http://localhost/users
users_path: /users
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.