ssig33.com

Ruby On Rails でサブドメインを使った Web サイトを作る

という地獄の話です。

基本的な部分

# config/initializers/session_store.rb
Hogehoge::Application.config.session_store :cookie_store, domain: ".#{ENV['DOMAIN']}", key: '_hogehoghoge'

というような感じにする。アプリを起動する時に環境変数でドメインを指定する。 .#{ドメイン} と cookie のドメインを指定しておくことでサブドメインでもクッキー共有できるようにする。クッキー共有したくないならこうしない。 ./bin/rails server とかを使うなら、この場合 localhost としてアプリが起動するのだから、

DOMAIN=localhost ./bin/rails server

とかする。 hoge.localhost とかで名前解決出来るように hosts ファイルをいい感じに書くか、 dnsmasq などを使って開発用の DNS サーバーを立てる。

ルーティング

def sub_domain? req
  if req.subdomain.blank?
    return false
  else
    if req.subdomain == 'www' # www はサブドメインアクセスと見做さないとかならこうする
      return true
    else
      domain = "#{req.subdomain}.#{req.domain}"
      return domain == ENV['DOMAIN']
    end
  end
end

というようなものを route.rb に書いて、以下のように使う。

# サブドメインじゃないページで表示したいもの
match '/', to: 'hoge#fuga_action', constraints: lambda { |r| !sub_domain?(r) }, via: [:get] 
# サブドメインなページで表示したいもの
match '/', to: 'for_subdomain#fuga_action', constraints: lambda { |r| sub_domain?(r) }, via: [:get]

ドメインごとにふりわけとかしたい場合は頑張ってください。

テスト

コントローラに対してテストを書きたい場合には以下のようにする。

controller.request.stub(:subdomain).and_return("subdomain")

Capybara を使って実際のユースケースを模倣したようなテストを書く時には Capybara.app_host を随時上書きして頑張る。 Capybara WebKit を使いたいときはこちらを読んでください。

本質的な解決策

複数の Rails アプリに分割し、 OpenID などを用いて連携することが出来ないかを考えるのもよいアイディアだと思う。 cookie の domain を設定してサブドメインとも cookie を共有することまでは難しくないが、ルーティングの記述やテストなどでだるいことが多すぎるので。

サブドメインを使ったアプリを単独の Rails アプリとして作成することは大変に困難がともなう。とても辛い。基本的にやらないほうがよい。サブドメインを使うことを止めるというのはいいアイディアだと思う。

back to index of texts


Site Search

Update History of this content