QA@IT

request.formatを変更したとき、Missing templateとなる。

4713 PV

現在rails3.2でモバイル対応をしているのですが、PCでは正常に表示されるものが、 モバイルからだとMissing templateとなります。

具体的に状況を説明させていただきます。

まず現在作っているサイトの仕様の話なのですが、キーワード等で検索をかける際に、/blogs/search?word="hoge"この様なURL設計にしたかったので、下記の様にコントローラを書きました。(routes.rbは省略)

class BlogController < ApplicationController
  def index
    @blogs = Blog.all
    _index
  end

  def index_search
    @blogs = Blog.find(params[:word])

    _index
  end

  def _index
    respond_to do |format|
      format.html { render :action => "index"}
    end
  end

このような感じで、_indexでformat.html { render :action => "index"}と書く事によって、index_searchというメソッド名からでも、indexと同じView(index.html.erb)を見る様にしています。

このサイトにモバイル対応をするために、下記の様な処理をコントローラに追加しました。

class BlogController < ApplicationController
  layout :set_layout
  before_filter :set_iphone_format

  def set_iphone_format
    request.format = :iphone if iphone_request?
  end

  def set_layout
    iphone_request? ? "iphone" : "application"
  end

  private

  def iphone_request?
    request.user_agent =~ /(Mobile.+Safari)/
  end

これによって、index.iphone.erbというViewファイルを用意しておけば、レイアウトを切り替える事が出来る様になりました。

ここからが本題なのですが、
iPhoneから/blogs/search?word="hoge"にアクセスすると、Missing templateというエラーがでます。
 /blogsには、普通にアクセスできます。

なぜこのようなエラーがおこるのでしょうか?
ご回答いただけると助かります。

回答

(config/initializers/mime_types.rb などに Mime::Type.register_alias "text/html", :iphone のようなコードが書かれており、app/views/layouts/iphone.html.erb があるものとして回答します。)

Missing Template エラーが発生する理由は、BlogContoller#_indexrespond_to ブロックに format.html しか書かれていないためです。

期待する挙動にするためには、BlogContoller#_index を下記のように修正します。

def _index
  respond_to do |format|
    format.html { render :action => "index"}
    format.iphone { render :action => "index"}
  end
end

respond_to は format ごとにどのようなレスポンスを返すかを定義するメソッドです。

質問のケースでは format が iphone である時にどのようなレスポンスを返すか定義していないめに、デフォルトの動作 (アクションと同じ名前のテンプレートを使用) になってしまっています。

そのため、index アクションのときには index.iphone.erb を使用するものの、index_search アクションのときは index_search.iphone.erb を使用しようとして失敗する、ということです。

編集 履歴 (0)
  • うーん、なるほど。
    format.???というのは各フォーマットが来たときにどのような処理をするかを、書くための物だったんですね。
    そしてそれを省略した場合は、メソッド名.???.erbを見るという感じでしょうか。

    ありがとうございます。色々勉強になりました。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。