В комментариях к ответу Криса я упоминал, что вы можете использовать подстановочные знаки и регулярные выражения в имени_сервера, и они будут переданы вашему экземпляру rails.
server_name *; # handle requests from all domains
Существует четыре способа использования этого вваше Rails-приложение (о котором я знаю).
Метод "Big Bag of Content"
Ничего не делать
Если вы просто разрешите Nginx отправлять все домены наодно и то же приложение, они получают одинаковое содержимое.В этом случае www.abc.com и www.xyz.com могут получить доступ к одним и тем же данным.Это проще всего сделать, потому что вы ничего не делаете.
Ограничение этого решения возникает тогда, когда вы хотите, чтобы домены имели разный контент.Например, становится сложно, если www.abc.com/about и www.xyz.com/about должны быть разными страницами.
Метод «Человек за занавесом»
Использование«Переписать» Nginx
При определенных обстоятельствах вы можете позволить Nginx переписать доменное имя в поддомен и передать его в ваше приложение rails.Например:
server_name *; # handle requests from all domains
rewrite ^(?:www.)?([^.]*)\..*$ $1.yourdomain.com last;
Это регулярное выражение нуждается в небольшом объяснении.Он просто говорит, что вы можете получить только xyz от любого из них: www.xyz.com, xyz.com, xzy.co.uk, www.xyz.co.uk.Перезапись изменяет запрос с любого из них на xyz.yourdomain.com.
Преимущество этого заключается в том, что Nginx делает это очень быстро, приложение rails не задействуется до позднего времени, и запрос контента может быть ограничен.на поддомен.Page.where(subdomain: request.subdomain, permalink: params[:permalink])
например.
Это довольно ограничительно, хотя, потому что это означает, что поддомен и имя домена должны быть одинаковыми.Может быть, это проблема для вашего приложения, а может и нет.Но хотя я использую $1
здесь, в поддомене, вы можете так же легко вставить его в качестве параметра в URL.Например, yourdomain.com/$1
перезапишет запрос от www.xyz.com на yourdomain.com/xyz.
Еще одна проблема - «человек за занавесом».Хотя пользователь заходит на www.xyz.com, переписывание означает, что он увидит xyz.yourdomain.com в адресной строке.
Метод "Rails Way"
Использование объекта запроса Rails вApplicationController
Вы можете использовать свой контроллер приложений для выделения содержимого, связанного с доменным именем, используя объект Rails 'request
.
В этом примере мы будем использовать ApplicationController для поискаучетная запись пользователя, связанная с именем домена.Предполагая, что у вас есть модель User с атрибутом domain_name
:
def domain_user
@domain_user ||= User.where(domain_name: request.domain()).take
end
Redis можно использовать для кэширования этих поисков, если дополнительные попадания в вашу базу данных создают барьер производительности.До сих пор я не достиг этой точки в своих приложениях.
Слабость этого решения в том, что, хотя поиск может найти www.xyz.com, он пропустит xyz.com.Чтобы приспособиться к этому, мы можем использовать некоторое регулярное выражение:
def domain_user
request.domain.match /(?:www.)?(.*)/
@domain_user ||= User.where(domain_name: $1).take
end
Это регулярное выражение удаляет www.если он присутствует.Остальное становится доменом (который рубин хранит для нас в $1
).
В отличие от решения для перезаписи Nginx, если пользователь заходит на www.xyz.com, это то, что он все еще видит в адресной строке.
Использование ограничений маршрутизации
Метод "Не работает для меня"
В качестве альтернативы, Rails 3 и выше имеют ограничения, функции, которые существуют в вашем файле маршрутов, которые генерируют маршрутизациюстол полудинамически.Я говорю «полудинамически», потому что таблица маршрутизации генерируется при запуске приложения.Если модель User (в нашем примере) изменяется, особое внимание следует уделить перестройке таблицы маршрутов.Для приложений, распределенных по нескольким серверам, это может стать громоздким для управления, хотя люди сделали это .
Пока что все мои приложения в конечном итоге, если не изначально, использовали решение ApplicationControllerпотому что он оказался самым чистым и легко реализуемым.Это также имеет большой смысл с точки зрения MCV.