Tortoise-like pace

toshibohjp

[RoRGuides] #06 Post を新規作成する

| Comments

前回 は、Post オブジェクトはひとつも作ってませんが、一覧表示できるようにしました。今回は Post オブジェクトを新規作成するための仕組みを見てみましょう。

6.9 Post を新規作成する

新しい Post を新規作成することは二つのアクションを含みます。ひとつめは new アクションです。このアクションは空の Post オブジェクトを作成します。以下は、app/controllers/posts_controller.rb の一部です。

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

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

コード内に記述されている new.html.erb View は空の Post をユーザーに表示します。

app/views/posts/new.html.erb
1
2
3
4
5
<h1>New post</h1>

<%= render 'form' %>

<%= link_to 'Back', posts_path %>

<%= render 'form' %> の行は Rails の Partial についての最初の紹介です。Partial とは HTML と Ruby のコードのスニペットで、複数の場所で再利用ができます。この場合においては、 新しい Post を作成する form は基本的に Post を編集するものと同じものが使用されており、両方とも name と title を持つテキストフィールド、content のためのテキストエリア、そして Post を新規作成および既存の Post を更新するためのボタンを持っています。

app/views/posts/_form.html.erb ファイルを見ると、以下のようになっているでしょう。

app/views/posts/_form.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
28
29
<%= form_for(@post) do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @post.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :content %><br />
    <%= f.text_area :content %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Partial は呼び出し側の View ファイルで定義されたインスタンスのすべてを受け取ります。この場合では、Controller が新しい Post オブジェクトを @post に割り当て、このように @post として View と Partial の両方で利用可能になります。

Partial についてのより詳しい情報については、Layouts and Rendering in Rails ガイドを参照してください。

form_for ブロックは HTML フォームを生成するために使用されます。このブロック内では、フォーム上の様々なコントロールを作成するためのメソッドにアクセスしています。例えば f.text_field :name は Rails にフォーム上にテキストボックスを作成し、表示されているインスタンスの name 属性につなげるように指示します。フォームの元になっている Model の属性(この場合においては nametitle、そして content) とメソッドのみを使用できます。Rails はコードをより簡潔にするため、かつ明示的に特定の Model インスタンスへフォームを結びつけるために、あなたが記述した生の HTML より form_for を優先して使用します。

form_for ブロックはまた、新しい Post や Post の編集をする場合では、充分にうまくこなすくらい賢く、HTML 出力内で action タグと「送信」 ボタンの名前を適切に設定します。

Model に結び付けられていない任意のフィールドを表示するように HTML フォームを作成する必要がある場合は、Model インスタンスに必ずしも関連付けらているわけではないフォームを作成するためのショートカットを提供する form_for メソッドを使用するべきです。

ユーザーがフォーム上で「Post の新規作成」ボタンをクリックしたときに、ブラウザは Controler の create アクションに情報を送り返すでしょう。(Rails はフォームが HTTP POST リクエストで送信されているので、 create アクションを呼ぶことを知っています。これが、前に言及した 規約 の一つです。)

対応する Controller のコードを以下に示します。

app/controllers/posts_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  # 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

create アクションは Rails が params ハッシュ内で利用できるようにしたフォーム上で、ユーザーによって入力されたデータから新規の Post オブジェクトをインスタンス化しします。新しい Post の保存が正常に行われた後、create はユーザーが求めた適切なフォーマット(今回の場合は HTML)を返します。そのときに、結果としてもたらされる Post の show アクションへユーザーをリダイレクトし、そしてユーザーに Post が”Post was successfully created.”(Post が正常に作成された)と通知します。

バリデーションエラーによって、Post の保存が失敗した場合には、Controller は、ユーザーにエラーを修正し再試行できるように、エラーメッセージと共に new アクションを返します。

メッセージが他のアクションに持ち越せるように、また、リクエストの状態の上で有用な情報をユーザーに提供できるように、”Post was successfully created.” メッセージは Rails の flash ハッシュ内に格納されます(通常、単に flash と呼ばれます)。create の場合においては、Post の生成プロセスの間に、ユーザーが実際にどのようなページがレンダリングされているかを見ることはないでしょう。これは、Rails がレコードを保存してすぐに、新しい Post にすぐさまリダイレクトされるからです。Flash はメッセージを次のアクションに持ち越します。ユーザーが show アクションにリダイレクトされたときに、”Post was successfully create.” というメッセージが表示されるためです。

次回 に続きます。

Comments