Маршрутизация Rails 3 и несколько доменов
Мое приложение позволяет людям создавать портфели. Я хотел бы, чтобы они могли подключить свой домен к своему портфолио.
Так что somedomain.com будет показывать/портфолио/12, someotherdomain.com будет показывать/портфолио/13 и так далее. Но я не хочу перенаправления. Я хочу, чтобы пользователь увидел somedomain.com в URL-адресе браузера.
Как мне это сделать?
Хорошо, я нашел это решение:
match "/" => "portfolio#show",
:constraints => { :domain => "somedomain.com" },
:defaults => { :id => '1' }
Поскольку у меня не так много настраиваемых доменов, на данный момент это нормально, но возникает вопрос: как сделать эту динамику, читать данные домена и идентификатора из db?
Ответы
Ответ 1
Во-первых, вы должны добавить поле в модель портфеля для хранения домена пользователя. Убедитесь, что это поле уникально. Добавление индекса в поле в вашей базе данных также было бы разумным.
Во-вторых, установите корень для перехода к действию portfolios#show
, как вы это делали, но без ограничений.
Затем в методе PortfoliosController#show
выполните следующую проверку:
if params[:id]
@portfolio = Portfolio.find(params[:id])
else
@portfolio = Portfolio.find_by_domain(request.host)
end
После этого остается только убедиться, что ваш собственный домен не вызывает действие portfolio#show
. Это можно сделать с помощью ограничения, которое вы использовали ранее, но теперь с вашим собственным доменом. Обязательно поместите эту строку в route.rb над строкой для действия portfolio#show
, так как приоритет основан на порядке создания.
Ответ 2
Хорошо, предположим, что вы владеете yourdomain.com
и используете его как свою домашнюю страницу для своего приложения. И любое другое доменное имя, подобное somedomain.net
, отображается на страницу портфолио.
Прежде всего, в вашем routes.rb
вам нужно поймать yourdomain.com
и отобразить его везде, где есть ваша домашняя страница, чтобы он выделялся из остальной толпы.
root :to => "static#home", :constraints => { :domain => "yourdomain.com" }
Затем вам нужно поймать любой другой корень в любом домене и переслать его на PortfoliosController
root :to => "portfolios#show"
Имейте в виду, что эта строка будет проверяться только в том случае, если предыдущая строка не соответствует.
Затем в вашем PortfoliosController
найдите запрошенное портфолио по его домену, а не по идентификатору.
def show
@portfolio = Portfolio.find_by_domain(request.host)
…
end
Конечно, вы можете избавиться от исключения ActiveRecord::RecordNotFound
в случае, если домен отсутствует в вашей базе данных, но оставьте это для другого обсуждения.
Надеюсь, что это поможет.
Ответ 3
Кажется, объект request
недоступен для файла routes.rb
без каких-либо исправлений.
Есть некоторые плагины, которые делают его доступным, но большинство из них, похоже, устарели. Здесь request_routing, похоже, с самыми последними датами фиксации, поэтому он будет наиболее актуальным. Хотя я сомневаюсь, что он будет работать с Rails 3.0 из коробки, это начало, и его не так уж сложно портировать.
Ответ 4
Ваши пользователи могут настроить DNS-переадресацию CNAME так, чтобы запросы на theirdomain.com
попадали на your_app.com/portfolio/12
.