Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
48
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

Ruby on Railsのアプリをサブディレクトリで動かす場合のメモ

たまにRuby on Railsでアプリを作るのだけれどいつも忘れてしまうのでメモ。いろいろな人がすでに書いてるけど自分がよく使う環境に関連したマトメ。Ruby on Rails v4.2.0での動作確認も兼ねて。

Ajax関連

AjaxでアクセスするURLをJavaScriptでハードコーディングするとサブディレクトリで動かしたときに404になって困るのでファイルの拡張子をjs.erbとかjs.coffee.erbとかにしてRailsの機能でURLを生成するようにする。

例えばこんな感じ?

app/assets/javascripts/application.js.coffee.erb
<%= Rails.application.config.relative_url_root %><%= Rails.application.routes.url_helpers.search_people_path(format:'json') %>

なんか一発で取れるメソッドとかありそうな気もするし文字列連結してるのもちょっと嫌な感じもするけど、とりあえずこれで。

で、このRails.application.config.relative_url_rootについては当該ソースコードを見れば以下のように環境変数RAILS_RELATIVE_URL_ROOTの値が代入されていることがわかる。

railties-4.2.0/lib/rails/application/configuration.rb
@relative_url_root = ENV["RAILS_RELATIVE_URL_ROOT"]   

ちなみにActionController::Base.relative_url_rootでも取得できる。当該ソースコードは以下のような感じなので、結局はRails.application.config.relative_url_root経由でRAILS_RELATIVE_URL_ROOT由来の値。

actionpack-4.2.0/lib/action_controller/railtie.rb
options.relative_url_root ||= app.config.relative_url_root

Rails.application.config.relative_url_rootActionController::Base.relative_url_rootの使い分けはよく分からないが、より上流にある前者の方が良い気もするし、コントローラ的には後者の方が良い気もするけど、私は元気です。

開発環境

Rails With Relative URL Rootの「結局おすすめは」を参考にして設定すると変更箇所も少なくうまくいった。

config.ruを以下のように書く。ここはRails.application.config.relative_url_rootの方がしっくりくる感ある。うむ。

config.ru
require ::File.expand_path('../config/environment', __FILE__)
map Rails.application.config.relative_url_root || '/' do
  run Rails.application
end

サーバの起動時には環境変数RAILS_RELATIVE_URL_ROOTに値を指定する。

$ RAILS_RELATIVE_URL_ROOT=/piyo rails server

あ、最近はspringを使うのかい。インスタンスを再利用してくれて叩き直しが早いらしい。bundleとか使ってもう少ししつこく書くとこう。あと--bind=0.0.0.0すると他のマシンからでもアクセスできるよ。

$ RAILS_RELATIVE_URL_ROOT=/piyo bundle exec spring rails server -p 3000 --bind=0.0.0.0

ウェブブラウザからは以下のURLでアクセスできる。

http://localhost:3000/piyo/

本番環境

アセットのプリコンパイル

production環境だとデフォルトではassetsは動的にコンパイルされないのであらかじめコンパイルしておくのがたぶん普通。こっちの方がはやいもんね。でrake assets:precompileがそのプリコンパイルするRakeタスク。初心者はこれで泣きながら1日くらいさまよう罠。この時に環境変数RAILS_RELATIVE_URL_ROOTを指定して実行するのを忘れちゃいけない。

うちはDebianなので以下のような感じで実行する。rake assets:precompileを実行するとpublic/assets以下へ色々とコンパイルの成果物が配置されるわけだけどwww-dataってユーザでファイルを生成しとくのがたぶん普通。

sudo -u www-data -H bundle exec rake assets:precompile RAILS_ENV=production RAILS_RELATIVE_URL_ROOT=/piyo

Passengerの設定

Apache2の設定ファイルは以下な感じにする。PassengerBaseURIの値が環境変数RAILS_RELATIVE_URL_ROOTにセットされる。この辺は公式サイト参照。あと、PassengerRubyで実行させたいRubyの実行ファイルを指定できるので、色んなバージョンのアプリを動かすときに助かる。なお、Passengerは公式マニュアルをよく読んでから使ったほうが良い気がする。急がば回れ。

/etc/apache2/sites-enabled/000-default
Alias /piyo /srv/rails/piyo/public
<Location /piyo>
  SetEnv SECRET_KEY_BASE 秘密の文字列
  PassengerEnabled on
  PassengerRuby /usr/local/bin/ruby
  PassengerBaseURI /piyo
  PassengerAppRoot /srv/rails/piyo
  PassengerUser www-data
</Location>
<Directory /srv/rails/piyo/public>
  Options -MultiViews
</Directory>

あと、DebianだとPassengerのモジュールの読込設定は/etc/apache2/httpd.confに書くんじゃあない。/etc/apache2/mods-availableの中を参考に然るべきファイルを設置してa2enmodで有効化する。この辺りはDebian流。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
48
Help us understand the problem. What are the problem?