Railsでタスク管理アプリを作成_5

# タスク管理アプリを作ってみよう(続き)

## 1. 前置き

### 1. 前提・事前作業

 * [こっちの投稿](http://qiita.com/fujimohige/items/edaa1e86e7b0dd315f9c)
 * 例によって[ドットインストール](http://dotinstall.com/lessons/basic_rails_v2/24901)の写経
 * [#15 エラーメッセージを表示しよう](http://dotinstall.com/lessons/basic_rails_v2/24915)から実施



## 2. エラーメッセージを表示しよう

* バリデーションエラーを表示させる
* `/home/vagrant/taskApp/app/Views` の `new.html.erb` を弄る。


```erb:ERB
<h1>Add New</h1>

<!-- フォーム -->
<%= form_for @project do |f| %>

<p>
  <!-- ラベル -->
  <%= f.label :title %> <br>
  <!-- フィールド -->
  <%= f.text_field :title %> <br>
  <!-- エラー存在チェック -->
  <% if @project.errors.any? %> 
    <!-- エラー情報取得 -->
    <%= @project.errors.inspect %>  
  <% end %>
</p>

<p>
  <!-- サブミット -->
  <%= f.submit %> <br>
</p>

<% end %>
```

* 未入力で「Create Project」を押下時、下記の通りエラー内容が表示された。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/40160/7775aa3d-c9e4-30c5-2234-ba17ac2cf0a7.png)

* エラー情報取得部を下記の通り変更
* titleというキーの配列の0番目を取得

```erb:ERB
    <%= @project.errors.messages[:title][0] %>  
```

* こんな感じに変わった

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/40160/8f43dbf7-f172-f016-d0c2-5061b74e22ee.png)

* 上記はデフォルトメッセージなので、独自メッセージに変更する。
* `/home/vagrant/taskApp/app/Models` の `project.rb` を弄る。

```rb:ruby
class Project < ActiveRecord::Base
  # 必須制御
  # 「project」を未入力の状態では保存できなくなる
  # validates :title, presence: true
  validates :title, presence: { message: "入力してください"} # 独自メッセージに変更
end

```
* こうなった

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/40160/a2b690ab-dd64-2873-5b12-4145112d6d5d.png)

* さらに文字数のチェックを追加

```rb:ruby
class Project < ActiveRecord::Base
  # 必須制御
  # 「project」を未入力の状態では保存できなくなる
  # validates :title, presence: true
   # エラーメッセージを定義（メッセージは独自定義）
  validates :title, 
    presence: { message: "入力してください"},
    length:   {minimum: 3, message: "短すぎます"}
end

```

* 未入力時は上記のメッセージで、3文字未満のときは下記メッセージになる。


![無題.png](https://qiita-image-store.s3.amazonaws.com/0/40160/bb185bcc-ebad-34b0-9ed5-06c179e4e4ab.png)


## 3. 編集フォームを作ろう

* 編集機能を追加
* 編集フォームを追加する
* `rake routes` の内容に従い定義する(`edit` Actionを作成する)

```
$ rake  routes

Prefix        Verb   URI Pattern                   Controller#Action
projects      GET    /projects(.:format)           projects#index
              POST   /projects(.:format)           projects#create
new_project   GET    /projects/new(.:format)       projects#new
edit_project  GET    /projects/:id/edit(.:format)  projects#edit
project       GET    /projects/:id(.:format)       projects#show
              PATCH  /projects/:id(.:format)       projects#update
              PUT    /projects/:id(.:format)       projects#update
              DELETE /projects/:id(.:format)       projects#destroy
root          GET    / projects#index
```
* この部分が対象

```
edit_project  GET    /projects/:id/edit(.:format)  projects#edit
```

* 更新処理はこの部分が対象(`update` Actionを作成する)
```
              PATCH  /projects/:id(.:format)       projects#update
              PUT    /projects/:id(.:format)       projects#update
```

* まずはリンクを作成
* `/home/vagrant/taskApp/app/Views` の `index.html.erb` を弄る。

```erb:ERB
<h1>Projects</h1>

<ul>
  <% @projects.each do |project| %>
  <li> 
    <!-- 登録情報参照ページへのリンク -->
    <%= link_to project.title, project_path(project.id) %> 
    <!-- 編集ページへのリンク -->
    <%= link_to "[Edit]", edit_project_path(project.id) %> 
  </li>
  <% end %>
</ul>

<p><%= link_to "Add New", new_project_path %></p>
```

* 編集画面用リンクができた（まだ遷移先は未定義）

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/40160/22367560-7a8c-0cca-9839-f3fda0c9efcb.png)

* Actionを追加してやる。
* `/home/vagrant/taskApp/app/Controllers` の `projects_controller.rb` を弄る。

```rb:ruby
class ProjectsController < ApplicationController


  # indexアクションを追加
  def index
    # @をつけた変数はviewでそのまま使用可能
    # Projectの全データを引っ張ってくる
    @projects = Project.all
  end

  # showアクションを追加
  def show
    @project = Project.find(params[:id])
  end

  # newアクションを追加
  def new
    @project = Project.new
  end

  # createアクションを追加
  def create
    # Formからの入力値を受け取る
    @project = Project.new(project_params)
    # データの保存
    if @project.save
      # saveがtrueだったらHOMEへ移動
      redirect_to projects_path
    else
      # saveがfalseだったら入力フォームに戻る
      render 'new'
    end
  end

  # editアクションを追加
  def edit
    @project = Project.find(params[:id])
  end


  # project_params を定義
  private
    def project_params
      # projectでわたってきたもののうち、titleだけ使用
      params[:project].permit(:title)
  end


end
```

* フォームを作成する
* `/home/vagrant/taskApp/app/Views` の `edit.html.erb` を弄る。

```erb:ERB
<h1>Edit</h1>

<!-- フォーム -->
<%= form_for @project do |f| %>

<p>
  <!-- ラベル -->
  <%= f.label :title %> <br>
  <!-- フィールド -->
  <%= f.text_field :title %> <br>

  <!-- エラー存在チェック -->
  <% if @project.errors.any? %> 
    <!-- エラー情報取得 -->
    <%= @project.errors.messages[:title][0] %>  
  <% end %>

</p>

<p>
  <!-- サブミット -->
  <%= f.submit %> <br>
</p>

<% end %>
```

* HomeのEditリンク押下時、下記画面へ遷移できた
* ボタンが「Update Project」になってる

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/40160/adace4e6-7c35-656d-a743-1d53a237a740.png)


* `update`　Actionを作成する。
* `/home/vagrant/taskApp/app/Controllers` の `projects_controller.rb` を弄る。

```rb:ruby
class ProjectsController < ApplicationController


  # indexアクションを追加
  def index
    # @をつけた変数はviewでそのまま使用可能
    # Projectの全データを引っ張ってくる
    @projects = Project.all
  end

  # showアクションを追加
  def show
    @project = Project.find(params[:id])
  end

  # newアクションを追加
  def new
    @project = Project.new
  end

  # createアクションを追加
  def create
    # Formからの入力値を受け取る
    @project = Project.new(project_params)
    # データの保存
    if @project.save
      # saveがtrueだったらHOMEへ移動
      redirect_to projects_path
    else
      # saveがfalseだったら入力フォームに戻る
      render 'new'
    end
  end

  # editアクションを追加
  def edit
    @project = Project.find(params[:id])
  end

  # updateアクションを追加
  def update
    @project = Project.find(params[:id])
    if @project.update(project_params)
      redirect_to projects_path
    else
      render 'edit'
    end
  end

  # project_params を定義
  private
    def project_params
      # projectでわたってきたもののうち、titleだけ使用
      params[:project].permit(:title)
  end


end
```

* これで、更新処理の実装が出来た。（新規登録と見栄えに差は無いのでキャプチャは割愛）

* 新規登録 'projects/new' と更新の 'projects/edit' で、1行目しか差がない状態なので、モジュールを共通化させる
* `/home/vagrant/taskApp/app/Views` の `edit.html.erb` と `new.html.erb` を弄る(一行目のみ諒画面で異なる。)

```erb:ERB
<h1>Edit</h1>

<!-- フォーム -->
<%= render 'form' %>
```

* これだけになっちゃった。
* 代わりに、 `/home/vagrant/taskApp/app/Views` の `_form.html.erb` を作成する。
* アンダーバーつきのモジュールにすること。( __パーシャル__ )

```erb:ERB

<!-- フォーム -->
<%= form_for @project do |f| %>

<p>
	<!-- ラベル -->
	<%= f.label :title %> <br>
	<!-- フィールド -->
	<%= f.text_field :title %> <br>

	<!-- エラー存在チェック -->
	<% if @project.errors.any? %>	
		<!-- エラー情報取得 -->
		<%= @project.errors.messages[:title][0] %>	
	<% end %>

</p>

<p>
	<!-- サブミット -->
	<%= f.submit %> <br>
</p>

<% end %>
```

* `New` も `Edit` も `_form.html.erb` に記述された内容を利用する
* 挙動はこれまでと変更なし

続きは次の投稿