at posts/single.html

デザインを共有する

一覧表示 (list) は少し形になってきたけど、タイトルをクリックして表示される個別表示 (show) は scaffold のままになってる。 個別表示のビュー (show.rhtml) も同じように書き換えればいいんだけど、それだと似たようなソースが list.rhtml と show.rhtml の両方にできてしまう。

そこで、 render(:partial) という仕組みを使って、2つのビューでデザインを共有するようにした。 まず、 list.rhtml に書いていたページ描画部分(for 文の内側)を _page.rhtml に移す。 (パーツとして使われるビューは、アンダースコアから始める規約になっている)

$ vi app/views/note/_page.rhtml

  <div style="border: solid 1px #999; padding: 0.5em; margin: 1em">
    <h2 style="font-size: 110%; margin: 0.3em">
      <%= link_to truncate(page.title, 20), :action => 'show', :id => page %>
    </h2>
    <div style="font-size: 80%; background-color: #fcc">
      <%= link_to 'Edit', :action => 'edit', :id => page %>
      <%= link_to 'Destroy', { :action => 'destroy', :id => page }, :confirm => 'Are you sure?', :post => true %>
    </div>
    <%=h page.body %>
  </div>

list.rhtml と show.rhtml から、 _page.rhtml を参照する。 従来の for 文の代わりに、 :collection を使って繰り返しを実現している。 (:collection じゃなくて for 文を使っても問題は無い)

$ vi app/views/note/list.rhtml

<%= link_to 'create', :action => 'new' %>
<%= render(:partial => 'page', :collection => @pages) %>
$ vi app/views/note/show.rhtml

<%= link_to 'create', :action => 'new' %>
<%= render(:partial => 'page', :collection => @pages) %>
<%= link_to 'Back', :action => 'list' %>

これで、一覧表示と個別表示の両方で、同じデザインを共有できた。 ただ、本当は完全に同じだとダメで、一覧表示の方は本文の一部しか表示しないようにしなきゃいけない。 これは明日の課題かな。

screenshot (Ruby on Rails) - (5)

関連する日記