Rails で ToDo アプリをつくる③ (Rails 入門)

↓の続き

utouto97.hatenablog.com

今回やること

今回は、CRUD の C (Create) をやっていきます。
つまり、ToDo の新規作成をできるようにします。

フォームの作成

まずは、新規 ToDo の情報を入力するフォームを作成します。
HTMLとBootstrapで、フォームを作ります。

ビューの app/views/todos/index.html.erbのToDo一覧の上に、↓のフォームを追加しました。

<form action="/" method="post" class="mb-5 w-50 mx-auto">
  <input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
  <div class="form-group">
    <label for="title">Title</label>
    <input type="text" class="form-control" name="title" placeholder="Title" value=<%= @title %> />
  </div>
  <div class="form-group">
    <label for="description">Description</label>
    <textarea class="form-control" name="description" placeholder="Description"></textarea>
  </div>
  <button type="submit" class="mt-2 btn btn-primary">Add</button>
</form>

Title と Description の入力欄と Submit ボタンを用意しています。
フォームのアクションは/に、POSTメソッドでリクエストします。

ルーティングの設定

/にPOSTメソッドでリクエストされるので、これをtodos#createにつなぎます。
以下を追記します。

post '/' => 'todos#create'

コントローラーのアクション追加

ルーティングの設定により、todos#createが呼び出されるようになりました。
ですので、TodosControllercreate アクションを実装していきます。

app/controllers/todos_controller.rbに追加します。

  def create
    @todo = Todo.new(
      title: params[:title],
      description: params[:description],
      status: 'In progress'
    )

    @todo.save
    redirect_to :action => 'index'
  end

Title と Description は、パラメータから取得しています。
Status の初期値は、"In progress" としています。

新規ToDoの作成に成功した場合は、indexにリダイレクトしています。

バリデーション

最後に、Rails の機能を使って、簡易なバリデーションを追加します。

Todoモデルにバリデーションを追加します。
app/models/todo.rbを編集します。

class Todo < ApplicationRecord
  validates :title, presence: true, length: { maximum: 50 }
  validates :description, length: { maximum: 140 }
end

validates :属性名, 条件 という形でバリデーションを設定できます。
ここでは、空ではないこと (presence) と 長さ (length) をチェックするようにしています。

また、バリデーションのチェックはモデルのsaveメソッド呼び出し時に行われるので、TodosControllercreate アクションを少し変更します。

  def create
    @todo = Todo.new(
      title: params[:title],
      description: params[:description],
      status: 'In progress'
    )

    if @todo.save
      redirect_to :action => 'index'
    else
      @todos = Todo.all
      @title = params[:title]
      @description = params[:description]
      render 'index'
    end
  end

バリデーションチェックでダメな場合、saveメソッドがfalseを返します。
その場合、フォームに入力されていた情報と、エラー情報を含んだtodoオブジェクトを保持したまま、indexページをレンダリングします。
これにより、エラーで戻されたときに、フォームに入力されていた値をそのまま保持することができます。

バリデーションのエラーメッセージは、@todo.errors.full_messages_for(:title)で取得できます。
これを利用して、メッセージを表示するようにしました。

これで、ToDoの新規作成ができるようになりました。

続き

utouto97.hatenablog.com

終わり