public配下の任意の静的ファイルへのURLを作成するメモ

ローカルでは、http://localhost:3000/ で開発をしているが、
本番サーバで動かすときは、http://domain/prefix/ で動かしたい場合がある。


viewでリンクなどのURLを直書きしていると、相対パスなら大丈夫かもしれないが、
絶対パスは prefix があるせいで、本番サーバに持って行ったときに意図する動作(URL)にならない。

# viewファイル(直書きの例)
<a href="/controller/action">link</a>

<script type="text/javascript" src="/javascripts/prototype.js"></script>


上の例のように、aタグリンクであったり、
public配下であっても javascripts,stylesheets,images 下のファイルであれば、
railsが用意してくれている link_to, url_forや、
javascript_include_tag, stylesheet_link_tag, image_tag などを使うことで、
prefixの有無に関わらずrailsがよろしくURLを作ってくれる。

# viewファイル
<%= link_to "link", :controller => "controller", :action => "action" %>

<%= javascript_include_tag "prototype" %>


でも、それ以外の静的ファイルのURLに関して、どうするのがいいかちょっと困ったのでメモする。

# viewファイル
# 例えば、public/swf/example.swf とか
<embed src="/swf/examle.swf">

結論としては、当たり前のことかもしれないけど、
root_path を取得して、public配下のパスをくっつけるという方法しか思いつかなかった。
で、root_pathの取得の仕方は、 config/routes.rb で map.root を設定しているなら、
そのまま root_path で参照できる。

# viewファイル
<embed src="<%= "#{root_path}swf/examle.swf" %>">

これで、root_path には、ローカルなら '/' が、
本番サーバなら '/prefix/' が入るので、どちらの環境でも正しく動作する。


config/routes.rb で map.root を設定していない場合は、
次のような helper を作ると、同じことができる。

# helperファイル
def my_root_path
  return "#{ActionController::Base.relative_url_root}/"
end

# viewファイル
<embed src="<%= "#{my_root_path}swf/examle.swf" %>">


どうせなら、

# helperファイル
def url_for_public(path)
  return "#{ActionController::Base.relative_url_root}/#{path}"
end

# viewファイル
<embed src="<%= url_for_public "swf/examle.swf" %>">

ここまでやった方がきれいかもしれない。


(※) ちなみに、railsのversionは 2.3.5 です。
古いversionだと、ActionController::Base.relative_url_root ではなく、
request.relative_url_root で参照するようです。