読者です 読者をやめる 読者になる 読者になる

生涯未熟

プログラミングをちょこちょこと。

RailsによるアジャイルWEBアプリケーション開発第3版勉強!#4

Ruby on Rails

前回は管理アプリケーションの見た目をいじりました。
今回は商品のカタログを作成していきたいと思います。



カタログリストの作成


販売者側のアプリケーション操作は管理アプリケーションとして作成しましたので、次は購入者側のアプリケーションを作成します。
まず、Storeコントローラを作成します。

>ruby script/generate controller store index

これはindexというアクションメソッドを持ったコントローラstoreの作成という意味です。
何故indexというアクション名にしたかというと、アクションが何も指定されずに呼び出された場合は自動的にindexが呼び出されます。

そして、以下の画面が出れば作成成功です。

しかし、もし以下の画像のような結果が出た方はもう少しファイルをいじりましょう。


configフォルダ内のroutes.rbファイルの中にあるmap.resourcesを以下のように付け足してみてください。

map.resources :store

これで、無事にindexにルーティングされるはずです。


さて、連携が確認されたところでドンドン進みましょう。
次はカタログとしての機能である商品の表示をさせます。

今度はstore_controller.rbのindexメソッドを以下のように変えてください。

class StoreController < ApplicationController
  def index
        @products = Product.find_products_for_sale
  end
end


productsという変数にProductにあるfind_products_for_saleの情報を入れます。
しかし、find_products_for_saleなんてメソッドは作っていませんので作成します。
手を加えるファイルはapp/models/product.rbで、以下のコードを追加します。

def self.find_products_for_sale
    find(:all, :order => "title")
end

findメソッドを使ってテーブルを探索し、引数には第1に行全てを取ってくるという意味のallをつけ、第2には順序を表すorderでtitle順に取ってくるように指定しています。
このself.find_products_for_saleの形はクラスメソッドを示しているのですが、クラスメソッドがイマイチ何を指しているのかが分からないので今回はスルーで。(Rubyはまだまだ勉強不足ですorz)

最後に、ビューをいじりましょう。
あの素っ気ない表示だったapp/views/storeのindex.html.erbに手を加えます。

<h1>Pragmaticカタログ</h1>
<% for product in @product -%>
 <div class="entry">
  <%= image_tag(product.image_url) %>
  <h3><%=h product.title %></h3>
  <div class="price-line">
  <span class="price"><%= product.price %></span>
  </div>
 </div>
<% end %>

まず、商品情報を全て表示するように先ほどの@productsの中身を全部for文で吐き出します。
情報の形式はCSSを使い、テーブル内の情報に沿って整理されています。
もし、どんな風に@productsに入っているかを知りたい場合はdb/schema.rbを参照してみてください。

これで、ひとまず仮完成になります。
ブラウザ上にはこんな画面が表示されているはずです。


ページにレイアウトを追加

Railsにはコンテンツを流し込むことが出来るテンプレートが存在しています。
しかし、仮にもテンプレートなので個々のデザイン性を高めるにはページ別に改造が必要になることをお忘れ無く。

それでは、レイアウトを一つ作ってみましょう。
app/views/layoutsフォルダstore.html.erbを作成してみます。
ちなみにstoreという名前にすることでそのコントローラで使われるビュー全てに適用されます。

<head>
  <title>Pragprog Booksオンラインストア</title>
  <%= stylesheet_link_tag 'depot' :media => "all" %>
</head>
<body id="store">
 <div id="banner">
  <%= image_tag("logo.png") %>
  <%= @page_title || "Pragmatic Bookshelf" %>
 </div>
 <div id="colums">
  <div id="side">
   <a href="http://www....">ホーム</a><br />
   <a href="http://www..../faq">よくある質問</a><br />
   <a href="http://www..../news">ニュース</a><br />
   <a href="http://www..../contact">お問い合わせ</a><br />
  </div>
  <div id="main">
   <%= yield :layout %>
  </div>
 </div>
</body>
</html>

まず、めぼしいところと言えば<%= stylesheet_link_tag 'depot' :media => "all" %><%= @page_title || "Pragmatic Bookshelf" %><%= yield :layout %>でしょうか。

1つ目は、:media => "all"とありますがこれはmediaという属性名にallという属性値を与えますよという命令です。
これによってstylesheets_link_tagによってスタイルが印刷可能になるなどがあります。

2つ目は、インスタンス変数@page_title内の値をページの見出しに設定と書いてあるのですが正直この部分がどいう構造なのか良く分かりませんorz

3つ目は、このレイアウトに該当するビューのコンテンツを呼び出しているのです。
この場合は、index.html.erbですね。

と、ここで自分でミスを発見。
先ほどのindex.html.erbファイルを以下に直してください。

<h1>Pragmaticカタログ</h1>
<% for product in @product -%>
 <div class="entry">
  <%= image_tag(product.image_url) %>
  <h3><%=h product.title %></h3>
  <%= product.description %>
  <div class="price-line">
  <span class="price"><%= product.price %></span>
  </div>
 </div>
<% end %>

これで、商品の下に商品説明が入ります。


続きを進めます、depot.cssにレイアウトに使われている部分を追加していきます。

#banner {
 background: #9c9;
 padding-top: 10px;
 padding-bottom: 10px;
 border-bottom: 2px solid;
 font: small-caps 40px/40px "Times New Roman", serif;
 color: #282;
 text-align: center;
}

#banner img{
 float: left;
}

#colums {
 background: #141;
}

#main {
 margin-left: 13em;
 padding-top: 4ex;
 padding-left: 2em;
 background: white;
}

#side {
 float: left;
 padding-top: 1em;
 padding-left: 1em;
 padding-bottom: 1em;
 width: 12em;
 background: #141;
}

#side a{
 color: #bfb;
 font-size: small;
}

これらを付け加えます。
これらが何を指しているか詳しいことが知りたい方はCSSの関連サイトを参照すると良いでしょう。


さて、これでブラウザ上に以下の画面が表示されるはずです。




今回はここまで。
次回は、カタログを完成させるところまでやりたいと思います。