第4回 Ruby on Rails 〜タスク管理アプリケーション CRUD機能の実装①〜

Bootstrap

今回は以前作成したタスク管理アプリケーションに機能を実装していきます。

実装する機能は下記の通りです。

  • ・一覧表示機能
  • ・新規登録機能
  • ・詳細表示機能
  • ・編集機能
  • ・削除機能

上記のうち今回は新規登録機能と一覧表示機能を実装します。
それでは進めていきましょう。

新規登録機能

まずは新規登録機能を実装します。

新規登録におけるユーザーの操作としては、まずはタスク一覧画面が表示され、その中にある「新規登録」のリンクをクリックして新規登録画面に遷移します。この登録画面に必要な値を入力して「登録する」を押すとタスクが登録され流ようにします。

このような動きをするためには、下記の画面とアクションが必要になります。

それでは一覧表示から順に開発していきましょう。

一覧画面に新規登録リンクを追加する

一覧画面(app/views/tasks/index.html.slim)に、新規登録画面に遷移するリンクを設置します。
この際、btn、btn-primaryというcssクラスを与えることでbootsrapがリンクをボタンのような外見にしてくれます。

h1 タスク一覧

app/views/tasks/index.html.slim

h1 タスク一覧

= link_to '新規登録', new_task_path, class: 'btn btn-primary'

Slimにおいて=で始まる行はRubyのコードを実行してその結果を出力します。
コードを実行するだけの場合は-から始めます。

link_toメソッドは、<a href=”…”>新規登録</a>というHTML要素を出力するメソッドです。

new_task_pathはURLヘルパーメソッドで、これを呼び出すことで”/task/new”というURL文字列を取得します。URLヘルパーメソッドは、route.rbの定義によって自動生成されます。

モデルの翻訳情報を追加

次に、登録フォームを作っていきますが、その下準備としてTaskモデルの翻訳情報をconfig/locales/ja.ymlに追加します。以下のような情報を1箇所に定義しておくことで、コードのあちこちに個別で記載する必要がなくなります。

config/locales/ja.yml

ja:
  activerecord:
    errors:
      messages:
        record_invalid: "バリデーションに失敗しました: %{errors}"
        restrict_dependent_destroy:
          has_one: "%{record}が存在しているので削除できません"
          has_meny: "%{record}が存在しているので削除できません"
    models:
      task: タスク
    attributes:
      task:
        id: ID
        name: 名称
        destription: 詳しい説明
        created_at: 登録日時
        updated_at: 更新日時

以上でモデルの翻訳情報設定完了です。

新規登録画面のためのアクションを実装

app/controllers/tasks_controller.rbのnewアクションで、新規登録画面の表示に必要な準備をします。
ここでは登録フォームをスムーズに描画するために、インスタンス変数@taskに新しいTaskオブジェクトを代入します。

def new
    @task = Task.new
end

コントローラのインスタンス変数は、ビューからも見れます。アクションからビューに渡したいデータをインスタンス変数に入れることがアクションの基本的な役割の一つです。

また、アクションにはブラウザにどの画面を返すか記述できます。この記述を省略した場合は、アクション名に対応する画面(app/views/[コントローラ名]/[アクション名].html.slim)を表示します。
今回はnewアクションに対してnew画面を表示するので省略します。

新規登録画面のビューを実装

新規登録画面を作成します。既に作成されているapp/views/tasks/new.html.slimを編集していきます。

app/views/tasks/new.html.slim

h1 タスクの新規登録

.nav.justify-content-end
  = link_to '一覧', tasks_path, class: 'nav-link'

= form_with model: @task, local: true do |f|
  .form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', id: 'task_name'
  .form-group
    = f.label :description
    = f.text_area :description, rows: 5, class: 'form-control', id: 'task_description'
  = f.submit '登録する', class: 'btn btn-primary'

form_withはモデルオブジェクトを使ってHTMLのform要素を作成するメソッドです。
form_withにmodel: @taskという引数を渡すことで対応づけます。

form内部のHTMLはform_withに渡すブロックの中に記述します。ブロック引数fに対してlabelやtext_fieldなどのメソッドを呼び出すことで、モデルオブジェクトの属性に対応するフィールドを出力します。そしてHTMLは以下の通り出力されます。

<form action="/tasks" accept-charset="UTF-8" method="post">
 <input type="hidden" name="authenticity_token" value="・・・">
 <div class="form-group">
  <label for="task_name">名称</label>
  <input class="form-control" id="task_name" type="text" name="task[name]">
 </div>
 <div class="form-group">
  <label for="task_description">詳しい説明</label>
  <textarea rows="5" class="form-control" id="task_description" name="task[description]"></textarea>
 </div>
 <input type="submit" name="commit" value="登録する" class="btn btn-primary" data-disable-with="登録する">
</form>

http://localhost:3000/tasks/newにアクセスして以下の画面が表示されれば成功です。

登録アクションを実装

TasksControllerのcreateアクションとして登録アクションを実装します。処理の流れとしては「登録フォームから送られてきたデータをデータベースに保管して、一覧画面に遷移する」です。
次のようにcreateアクションを記述します。

app/controllers/tasks_controller.rb

def create
  task = Task.new(task_params)
  task.save!
  redirect_to tasks_url, notice: "タスク 「#{task.name}」を登録しました。"
end

また、ファイル後方にtask_paramsというプライベートメソッドを記述します。

 private

  def task_params
    params.require(:task).permit(:name, :description)
  end
end

task_paramsメソッドでは、リクエストパラメータとして送られてきた情報が想定通りの形かチェックし、その中からnameとdescriptionだけを抜き取ります。

createアクションではtask_paramsメソッドで安全化されたtaskパラメータを取得し、これを基にTaskオブジェクトを作成します。次にsave!メソッドでデータベースに保存し、redirect_toメソッドで一覧画面に遷移します。

また、redirect_toメソッドには特定のFlashメッセージを渡すことができます。Flashは次のリクエストに対してちょっとしたデータを伝えるためにRailsが用意している仕組みです。

先程createアクションで記述したredirect_toのコードを見てみましょう。

redirect_to tasks_url, notice: "タスク 「#{task.name}」を登録しました。"

これはflash[:notice]にタスク登録完了メッセージをセットしてからリダイレクトするという意味です。redirect_toのオプションに直接渡せるFlashのキーは、デフォルトでは:noticeと:alertのみです。

Flashに入れたメッセージは画面に表示する必要があります。共通レイアウトのapp/views/layouts/application.html.slimに下記の通りに表示コードを追加します。
nilや空白でないnoticeのflashメッセージが存在すれば表示されます。

app/views/layouts/application.html.slim

.container
  - if flash.notice.present?
  .alert.alert-success= flash.notice
  = yield

新規登録機能の動作確認

ここまで実装できましたら実際にタスクを登録してみます。
名称と詳しい説明を入力して「登録する」ボタンをクリックします。

一覧画面に遷移して、上部にメッセージが表示されたら成功です。

しかしこのままでは、本当にタスクが登録されたのか画面から確かめることができません。
そこで、登録したタスクを参照する機能を実装していきます。

一覧表示機能

登録されたタスク全体を確認するために、一覧表示機能を実装します。今のところ一覧画面には「新規作成」ボタンを表示する部分だけできています。ここに登録された全てのタスクの名称と登録日時を表示する処理を追加します。

一覧表示アクションを実装

TasksControllerのindexアクションを以下のように編集します。

def index
  @tasks = Task.all
end

Task.allでデータベースに保存されている全てのタスクデータを取得し、@tasksというインスタンス変数に代入して、ビューに伝えます。
一覧表示アクションの実装は以上です。

一覧画面でタスクデータを表示する

次にビューを実装します。app/views/tasks/index.html.slimを以下のように修正します。

h1 タスク一覧

= link_to '新規登録', new_task_path, class: 'btn btn-primary'

.mb-3
table.table.table-hover
  thead.thead-default
    tr
      th= Task.human_attribute_name(:name)
      th= Task.human_attribute_name(:created_at)
  tbody
    - @tasks.each do |task|
      tr
        td= task.name
        td= task.created_at

@task.eachで@tasks内のTaskオブジェクトを一つずつ取り出し、それぞれの内容をテーブル形式で表示します。

ここまで実装できましたら、http://localhost:3000/tasksにアクセスしてみましょう。以下のように、これまで登録したタスクが全て表示されていれば成功です。タスクを一つしか登録していなければ、先に複数登録しておきましょう。

終わりに

今回はタスク管理アプリケーションにタスクの新規登録機能と一覧表示機能を実装しました。
次回は詳細表示機能、編集機能、削除機能を実装していきます。

コメント

タイトルとURLをコピーしました