ActionController::UrlWriter#url_forを色んなところで使うのは注意
最近、railsで作った自作ブログウェアでコメントが付けられなくなってました。何故かと言うとコメントを受け付けるurlがおかしかったからなんです。
なんでおかしかったか調べてみるとActionController::UrlWriter#url_forとActionController::Base#url_forの動作が異なってたから。
ってか、これってrailsのバグなんじゃね!?とか言ってみる。
ActionController::UrlWriter#url_for
「ユニットテストから link_to や url_for を使う方法 - Rails で行こう! - Ruby on Rails を学ぶ」や「 83's : url_forが使えないところで使えるようにする」の記事を見る限り、ActionController::UrlWriter#url_forはControllerとView以外でやむなくurl_forが使いたくなった時に利用するモジュールらしい。
ソースコードを見てみると、こんな感じでurlを組み立ててる。
def url_for(options)
options = self.class.default_url_options.merge(options)
url = ''
unless options.delete :only_path
url << (options.delete(:protocol) || 'http')
url << '://'
raise "Missing host to link to! Please provide :host parameter or set default_url_options[:host]" unless options[:host]
url << options.delete(:host)
url << ":#{options.delete(:port)}" if options.key?(:port)
else
# Delete the unused options to prevent their appearance in the query string
[:protocol, :host, :port].each { |k| options.delete k }
end
anchor = "##{options.delete(:anchor)}" if options.key?(:anchor)
url << Routing::Routes.generate(options, {})
return "#{url}#{anchor}"
end
- options{:protocol] || 'http'
- '://'
- options[:host]
- options[:port]
- Routing::Routes.generate(options, {})
- "##{options.delete(:anchor)}"
おー、urlが組み立てられてるよー。
ってことで早速自分のクラスでinclude ActionController::UrlWriterしてurl_forしてみました。
ところが、開発環境ではうまくいってたのですが、いざ本番環境で試してみるとうまくいかない。
期待したurlはこんな感じでした。
http://www.fraction.jp/rana3/comment/post
けど、実際に組み立てられたurlはこんな感じ。
http://www.fraction.jp/comment/post
そう、本番環境ではrails用のドメインを作るのがめんどかったのでmongrelの--prefixオプションを使ってrelative_url_rootを利用してたのです。まあ要するに[Rails] Rails の動作環境と Location について - プログラミングは素晴らしいで説明してるようなことをやってた訳です。
ところが、実際に組み立てられたurlがおかしい…。
Yuanying at 11時32分44秒 | Comments (0)








