Tortoise-like pace

toshibohjp

[RoRGuides] #05 すべての Posts を一覧にする

| Comments

前回 に引き続き Post Model を見ていきましょう。

6.7 すべての Posts を一覧にする

アプリケーションで我々の Post のリストが表示されているかを確認するために、少し深く Rails のコードの中に潜ってみましょう。app/controllers/posts_controller.rb を開いて index アクションを見てみましょう。

app/controllers/posts_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
class PostsController < ApplicationController
  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end
  end

  # GET /posts/1
  # GET /posts/1.json
  def show
    @post = Post.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @post }
    end
  end

  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end
  end

  # GET /posts/1
  # GET /posts/1.json
  def show
    @post = Post.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @post }
    end
  end

  # POST /posts
  # POST /posts.json
  def create
    @post = Post.new(params[:post])

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render json: @post, status: :created, location: @post }
      else
        format.html { render action: "new" }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /posts/1
  # PUT /posts/1.json
  def update
    @post = Post.find(params[:id])

    respond_to do |format|
      if @post.update_attributes(params[:post])
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /posts/1
  # DELETE /posts/1.json
  def destroy
    @post = Post.find(params[:id])
    @post.destroy

    respond_to do |format|
      format.html { redirect_to posts_url }
      format.json { head :no_content }
    end
  end
end

  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end
  end

  # GET /posts/1
  # GET /posts/1.json
  def show
    @post = Post.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @post }
    end
  end

長いコードになりましたが、ここでの重要部分は以下のコードです。

app/controllers/posts_controller.rb
1
2
3
4
5
6
7
8
9
10
  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end
  end

Post.all は現在のデータベース内にあるすべての Posts を、 @posts で呼ばれたインスタンス変数を格納している Post レコードの配列として返します。

ActiveRecord を使ってレコードを検索するより詳しい情報については、Active Record Query Interface を参照してください。

respond_to ブロックは、HTML と JSON が呼び出すアクションの両方を処理します。仮に、http://localhost:3000/posts.json をブラウザで参照した場合は、JSON 形式のすべての Posts が表示されることでしょう。HTML 形式はアクション名に対応する名前を持つ app/views/posts/ 内の View を見つけます。Rails は View が利用可能なように、アクションからすべてのインスタンス変数を作成します。ここで、app/view/posts/index.html.erb を見てみましょう。

app/view/posts/index.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<h1>Listing posts</h1>

<table>
  <tr>
    <th>Name</th>
    <th>Title</th>
    <th>Content</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @posts.each do |post| %>
  <tr>
    <td><%= post.name %></td>
    <td><%= post.title %></td>
    <td><%= post.content %></td>
    <td><%= link_to 'Show', post %></td>
    <td><%= link_to 'Edit', edit_post_path(post) %></td>
    <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New Post', new_post_path %>

上記の View は @posts 配列の内容やリンクを表示するためのコンテンツを each メソッドにより反復処理します。View で覚えておくべきいくつかのことは、以下の通りです。

  • link_to は特定の宛先へのハイパーリンクを生成する
  • edit_post_pathnew_post_path は、Rails が RESTful なルーティングの一部を提供するためのヘルパーです。Controller が含んでいる異なるアクションのための、様々なヘルパーを発見する事ができるでしょう。

以前のバージョンの Rails では、ページが挿入されようとする前に、どのような HTML もエスケープされるように <%=h post.name %> を使用する必要がありました。Rails 3 より後のバージョンでは、これはデフォルトの動作になりました。エスケープしていない HTML を得るためには <%= raw post.name %>を使用します。

レンダリングプロセスのより詳細については Layouts and Rendering in Rails を参照してください。

6.8 レイアウトをカスタマイズする

View はHTMLがどのようにブラウザ上に表示されるのかという話の一部分でしかありません。Rails はまた Layouts という概念を持っており、Layouts は View のコンテナです。Rails がブラウザへ View をレンダリングする時に、Layout の HTML の内側に View の HTML をおきます。以前のバージョンの Rails では、rails generate scaffold コマンドが自動的にコントローラー固有のレイアウトを作成していました。例えば、Posts Contolloer のための app/views/layouts/posts.html.erb のように。しかしながら、この仕様は Rails 3 では変更されました。アプリケーション固有のレイアウトはすべての Contoller で使用され、app/views/layouts/application.html.erb 内で見つける事ができます。エディタでこのレイアウトを開いて、以下のように body タグを変更してみましょう。

app/views/layouts/application.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
  <title>Blog</title>
  <%= stylesheet_link_tag    "application" %>
  <%= javascript_include_tag "application" %>
  <%= csrf_meta_tags %>
</head>
<body style="background: #CCCCCC;">

<%= yield %>

</body>
</html>

さて、/post ページを更新する時に、背景がグレーのページになっていることに気づくでしょう。この同じグレーの背景は、Posts に関連するすべての View で使用されることになります。原文ではグレーの色合いが白に近く、変化がわかりづらいので、このサンプルではもう少し暗めのグレーにしてあります。

背景がグレーになっている事がお分かりいただけるでしょうか?

今回の内容をまとめると、以下のようになります。

  • index アクションで HTML と JSON 形式のレンダリングに対応していることを確認した
  • index.erb で each メソッドで Post 全件をイテレートして表示していた
  • link_to は特定の宛先へのハイパーリンクを表す
  • app/views/layouts/application.html.erb の背景を変更することによって、すべての Controller に変更が波及している

次回 へ続きます。

Comments