Railsでtodoアプリを作った

# 下準備

まずはファイルを作成する
```
rails new rails-todo
```
でファイル作成。その後
```
cd rails-todo
```
で目的のディレクトリに移動
# Modelを作成
```
rails g model Task title:string
```
でstring型のtitleというカラム名を持ったTaskテーブルというモデルを作成した。
このままではデータベースに反映されていないので
```
rake db:migrate
```
でデータベースに反映させる。
# Controllerを作成する
```
rails g controller Tasks
```
でコントローラーを作成。コントローラーは基本複数形であることに注意。
次に作成されたコントローラーにアクションを追加。/tasksにアクセスした際のアクションを追加。Task.allで全タスクを取得。
```ruby:app/controller/tasks_controller.rb
class TasksController < ApplicationController
  def index
    @tasks = Task.all
  end
end
```
# Viewを作成する
app/views/tasks/index.html.erbを作成し，タスク一覧を表示させるために以下を記述する。
```erb:app/views/tasks/index.html.erb
<h1>タスク一覧</h1>
<table>
  <thead>
    <tr>
      <th>タスク名</th>
    </tr>
  </thead>
  <tbody>
    <% @tasks.each do |task| %>
      <tr>
        <td><%= task.title %></td>
      </tr>
    <% end %>
  </tbody>
</table>
```
次にルーティングを設定する。ルーティングとはブラウザからのリクエストに対してどのControllerのどのアクションを呼び出すかを設定する機能のこと。config/routes.rbを編集する
```ruby:config/routes.rb
Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  resources :tasks
end
```
```
rails routes
```
をターミナルに入力するとルーティングを確認することができる。
```
 Prefix Verb   URI Pattern               Controller#Action
    tasks GET    /tasks(.:format)          tasks#index
          POST   /tasks(.:format)          tasks#create
 new_task GET    /tasks/new(.:format)      tasks#new
edit_task GET    /tasks/:id/edit(.:format) tasks#edit
     task GET    /tasks/:id(.:format)      tasks#show
          PATCH  /tasks/:id(.:format)      tasks#update
          PUT    /tasks/:id(.:format)      tasks#update
          DELETE /tasks/:id(.:format)      tasks#destroy
```
これより，/tasksにアクセスした際はTasksコントローラーのindexアクションが実行されることがわかる。
# タスク追加機能
ここからは具体的に機能をつけていく。まずはタスク追加機能をつける。
```ruby:app/controllers/tasks_controller.rb
class TasksController < ApplicationController
  def index
    @tasks = Task.all
  end
  
  def new
    @task = Task.new
  end
  
  def create
    @task = Task.create(task_params)
    redirect_to tasks_path
  end
  
  private
    def task_params
      params.require(:task).permit(:title)
    end
end
```
と書き換え，newアクションとcreateアクションを追加した。privateを使うことでtask_paramsメソッドが外部から使えないようにしてセキュリティを高めている。/app/views/tasks/new.html/erbを作成し，以下のように書く。
```erb:app/views/tasks/new.html.erb
<h1>新規タスク</h1>
<%= form_for @task do |f| %>
  <div><%= f.label :title %></div>
  <div><%= f.text_field :title %></div>
  <div><%= f.submit %></div>
<% end %>
<%= link_to '戻る', tasks_path %>
```
また，トップページからのリンクも追加するので，index.html.erbの末尾に
```erb:app/views/tasks/index.html.erb
<%= link_to '追加', new_task_path %>
```
を追加。以上で追加機能は完成した。
# タスク編集機能
Controllerにeditとupdateアクションを追加。
```ruby:app/controllers/tasks_controller.rb
class TasksController < ApplicationController
  def index
    @tasks = Task.all
  end
  
  def new
    @task = Task.new
  end
  
  def create
    @task = Task.create(task_params)
    redirect_to tasks_path
  end
  
  def edit
    @task = Task.find(params[:id])
  end

  def update
    @task = Task.find(params[:id])
    @task.update(task_params)
    redirect_to tasks_path
  end
  
  private
    def task_params
      params.require(:task).permit(:title)
    end
end
```
タスク編集画面を作成するために，edit.html.erbを作成し，以下のように書く。
```erb:app/views/tasks/edit.html.erb
<h1>タスク編集</h1>
<%= form_for @task do |f| %>
  <div><%= f.label :title %></div>
  <div><%= f.text_field :title %></div>
  <div><%= f.submit %></div>
<% end %>
<%= link_to '戻る', tasks_path %>
```
トップ画面にタスク編集画面へのリンクを追加すれば完成！
```erb:app/views/tasks/index.html.erb
<% @tasks.each do |task| %>
      <tr>
        <td><%= task.title %></td>
        <td><%= link_to '編集', edit_task_path(task) %></td>
      </tr>
<% end %>
```
# 削除機能を追加
最後に削除機能をつける。controllerにdestroyアクションを追加。
```ruby:app/controllers/tasks_controller.rb
  def destroy
    @task = Task.find(params[:id])
    @task.destroy
    redirect_to tasks_path
  end
```
最後にトップ画面にタスク削除のリンクを追加すれば完了。
```erb:app/view/tasks/index.html.erb
<% @tasks.each do |task| %>
      <tr>
        <td><%= task.title %></td>
        <td><%= link_to '編集', edit_task_path(task) %></td>
        <td><%= link_to '削除', task_path(task), method: :delete %></td>
      </tr>
<% end %>
```
# 日本語に修正
これで完成でもいいが，このままだと，新規登録画面や編集画面の所々が英語表記になってしまう。個別にそれぞれ変更しても良いが，一括で変更することができるので，以下の手順で変更する。(これは最初の段階で毎回やった方がいいかもしれない)
/config/application.rbを開いて
```
config.i18n.default_locale = :ja
```
を追加
```ruby:/config/application.rb
require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module RailsTodo
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.
    
    config.i18n.default_locale = :ja
  end
end
```
この1文を追加することによってデフォルト言語を日本語に変更している。rails-i18nというものをインストールするためにGemfileに
```
gem ‘rails-i18n’
```
と追記する。
```ruby:Gemfile
source 'https://rubygems.org'

git_source(:github) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
  "https://github.com/#{repo_name}.git"
end

#日本語化
gem 'rails-i18n'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.0.7', '>= 5.0.7.2'
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.3.6'
```
ここまで書くことができたら
```
bundle install
```
して，サーバーを再度立ち上げると，日本語に変換されていることがわかる。しかし，まだ編集画面がTitleとなっていることがわかる(フィールド名が英語のまま)。
フィールド名も日本語にするには/config/localesディレクトリ内に，ja.ymlというファイルを新規作成して，以下のように書く。
```yaml:config/locales/ja.yml
ja:
  activerecord:
    attributes:
      task:
        title: タイトル
```
このja.ymlは日本語化するための設定ファイルのようなものである。これにより，
titleフィールド→タイトル
という翻訳ルールを定義していることになる。
# 削除機能の修正
現状では削除ボタンを押すとすぐに削除されてしまう仕様になっている。削除する際に確認ダイアログを表示させたい。JavaScriptを書かずともrailsならlink_toメソッドにオプションを一つ追加するだけでできる。
```erb:index.html.erb
<td><%= link_to '削除', task_path(task), method: :delete, data: {confirm: "本当に削除しますか？"} %></td>
```
以上で基本的な機能が完成した。
参考
https://rails-study.net/category/rails%e5%bf%98%e5%82%99%e9%8c%b2/
https://reasonable-code.com/rails-todo/