ルート
次のようにルートを設定して、Rails の組み込みのネストされたリソースを利用できます。
resources :documents, :only => [:index, :show] do
resources :chapters, :only => :show do
resources :pages, :only => :show
end
end
これは、次のカスタム ルートの設定とほぼ同じです。
get '/documents' => 'documents#index',
:as => 'documents'
get '/documents/:id' => 'documents#show',
:as => 'document'
get '/documents/:document_id/chapters/:id' => 'chapters#show',
:as => 'document_chapter'
get '/documents/:document_id/chapters/:chapter_id/pages/:id' => 'pages#show',
:as => 'document_chapter_page'
URL が思っていたよりも少し長くて扱いにくい場合、またはカスタム パラメーターを使用したい場合 (たとえば、ID ではなく番号でページを識別する場合) は、いつでも代わりにカスタム ルートを記述できます。
resources :documents, :only => [:index, :show]
get '/documents/:document_id/:id' => 'chapters#show',
:as => 'document_chapter'
get '/documents/:document_id/:chapter_id/:page' => 'pages#show',
:as => 'document_chapter_page'
詳細については、ルーティング ガイドを参照してください。
コントローラー
ユーザーが章に直接アクセスできるようにするのではなく、章の最初のページを表示する必要があります。ただし、章の URL がページ番号なしで機能することは間違いなく便利です (特に、ページ番号が章内の位置ではなくドキュメント内の位置を参照する場合)。
show
したがって、章コントローラーのアクションから最初のページにリダイレクトできます。
class ChaptersController < ApplicationController
def show
chapter = Chapter.find(params[:id])
redirect_to [chapter.document, chapter, chapter.pages.first]
end
end
ビュー
異なるビュー間で章のリストを共有するには、次の 2 つの方法があります。
モデル オブジェクトのコレクションをレンダリングするための Rails の組み込みサポートを使用します。あなたviews/documents/show.html.erb
とviews/chapters/show.html.erb
次のようなものを含めることができます(各アクションが@document
変数を設定すると仮定しています):
<ol>
<%= render @document.chapters %>
</ol>
Rails は と呼ばれる部分ビューを探し、views/chapters/_chapter.html.erb
それをチャプターごとにレンダリングします。次のようになります。
<li><%= link_to chapter, [chapter.document, chapter] %></li>
リスト全体を 1 つの部分で共有します。たとえば、次をviews/documents/show.html.erb
andに追加できviews/chapters/show.html.erb
ます。
<%= render 'chapters/list', :chapters => @document.chapters %>
と呼ばれる部分ビューを作成しますviews/chapters/_list.html.erb
。
<ol>
<% chapters.each do |chapter| %>
<li><%= link_to chapter, [chapter.document, chapter] %></li>
<% end %>
</ol>
詳細については、レイアウトとレンダリング ガイドのパーシャルの使用に関するセクションを参照してください。