RubyOnRails演習 (3)
ページング及びカテゴリーの親子関係のネスト構造をrender :partial等を用いて出力出来るようにしてみた
ページングなライブラリ
昔Rails使ってた時とかはwill_paginateとか使ってたような記憶があるのだけど、kaminariっていうライブラリがあるらしいのでそれを使う事にする
Gemfileに
gem "kaminari"
を記述。
rails g kaminari:views [THEME]
でkaminariが使うページングなUIなテンプレートを出力できる。別に出さなくても出来るんだけど、色々修正したいだとかTwitter Bootstrap方式なページングで出したいっていうのであれば
rails g kaminari:views bootstrap
等で出せる。app/views/kaminariに出力されるのでそれをいじればページングなUIを修正出来るっていう感じ。んまぁkaminariに関してはドキュメント読んだ方が良さそうなんで以降はある程度省略
app/controllers/entry_controller.rb
サイドバー的なところにカテゴリーをネストして出力出来るようにする為に、特定のアクションが起きる前に事前にカテゴリーデータを取得をおこなっておく。それはbefore_filterとかで良いと思う。利用されるアクションが1特定であれば普通にそのアクションでも良いとは思うけど、そうじゃないケースがあると思うので
class EntryController < ApplicationController
  before_filter :load_sidebar, :only => :index
  def load_sidebar
    @categories = Category.find_all_by_parent(0, :order => "sort ASC")
  end
  def index
    @entries = Entry.page(params[:page])
  end
end
とりあえず関係無い所なアクションは省略。load_sidebarでparentカラムが0(ルートカテゴリー)なデータを取得。それはrender :partialで利用する
app/views/entry/index.erb
<div class="row">
  <div class="span4">
    <!-- app/views/sidebar/_index.erbな部分テンプレートを読み込み -->
    <%= render :partial => "sidebar/index" %>
  </div>
  <div class="span8">
    <% @entries.each do |entry| %>
    <div class="entry">
      <% entry.category.each do |category| %>[<%= category.name %>]<% end %>
      <%= entry.title %>
    </div>
    <% end %>
    <div>
      <!-- ページングなビューを出力 -->
      <%= paginate @entries %>
    </div>
  </div>
</div>
今回関係ない所は省略。paginateなView Helperでページングなビューを表示。恐らくはapp/views/kaminari/_paginator.html.erbがレンダリングされるんだと
app/views/sidebar/_index.erb
<% @categories.each do |category| %>
  <%= render :partial => "sidebar/category", :locals => { :category => category } %>
<% end %>
load_sidebarで取得したカテゴリーなデータをレンダリングする。ここから更にapp/views/sidebar_category.erbに部分レンダリングされる
app/views/sidebar/_category.erb
<!-- エントリー数が無いカテゴリーもあるけど、そのカテゴリーがサブカテゴリーを持ってないとは限らない -->
<% if category.entry.size > 0 || category.sub_category.size > 0 %>
<ul>
  <li style="list-style: none;padding: 3px">
    <%= category.name %>
    <% category.sub_category.each do |sub_category| %>
    <%= render :partial => "sidebar/category", :locals => { :category => sub_category } %>
    <% end %>
  </li>
</ul>
<% end %>
んまぁ再帰でrender :partialをしてネスト構造を出力するような感じ。あんまりよくないケースだとは思いますが(遅い為)
ってな感じで、render :partialを使う事で部分的なテンプレートを差し込めたり出来るっていう事と、kaminariっていうページングライブラリを使う事でページングのビューをカスタマイズ出来る