【Rails】簡単な投稿アプリの作成

# 目的
Railsを使用し、簡単なアプリを作成する。

# 開発環境
macOS: Big Sur
rubyバージョン: 2.6.5
railsバージョン: 6.0.0
app名: test-app

# 手順

1. [アプリの立ち上げ](#アプリの立ち上げ)
1. [文字コードの変更](#文字コードの変更)
1. [データベースの作成](#データベースの作成)
1. [Gemのバージョン変更と追加](#gemのバージョン変更と追加)
1. [リセットCSSの設定](#リセットcssの設定)
1. [要素サイズの調整](#要素サイズの調整)
1. [ルーティングの設定](#ルーティングの設定)
1. [コントローラーの作成](#コントローラーの作成)
1. [モデルの作成](#モデルの作成)
1. [投稿一覧の表示](#投稿一覧の表示)
1. [投稿ページの実装](#投稿ページの実装)
1. [最終確認](#最終確認)

# アプリの立ち上げ

早速はじめていきましょう！
まずはアプリを立ち上げます。

```:ターミナル
rails _6.0.0_ new test-app -d mysql
```

アプリの立ち上げ自体は`rails new アプリ名`でできます。
今回は下記のような指定を追加しています！

`_6.0.0_`でrailsのバージョンを指定。
`-d mysqｌ`でdbを指定。

# 文字コードの変更

続いて文字コードの変更を行います。
下記のように`utf8mb4`を`utf8`に変更しましょう！

```ruby:config/database.yml
default: &default
  adapter: mysql2
  # encoding: utf8mb4
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock
```

`utf8`が1文字あたり3バイトであるのに対し、`utf8mb4`は1文字あたり4バイトになります。
MySQLではデフォルトで3バイトの文字までしか扱えないため、今回は`utf8`を使用していきます！


#データベースの作成

次にデータベースを作成していきましょう！

```:ターミナル
rails db:create
```

これでデータベースの作成ができました！

# Gemのバージョン変更と追加

次に既にあるGemのバージョンを変更する作業と、Gemを追加する作業を行います！
下記の2点を行いましょう！

- Gemfile内で、Gemである`mysql2のバージョンを0.5.3へ変更`
- Gemfile内で、Gemである`pry-railsを追加`

```ruby:Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.5'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.0'
# Use mysql as the database for Active Record
gem 'mysql2', '0.5.3'
# Use Puma as the app server
gem 'puma', '~> 3.11'

#中略

gem 'pry-rails'
```
記述できたら、下記コマンドでインストールしましょう！

```:ターミナル
% bundle install
```

こちらも忘れずに！

```:ターミナル
% rails s
```

# リセットCSSの設定

続いてリセットCSSを設定していきます！
今回はYahoo!が開発した「YUI 3」というリセットCSSを使用します。

```:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>ChatApp</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.18.1/build/cssreset/cssreset-min.css">
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>
#中略

</html>
```

これで設定完了です！

# 要素サイズの調整

続いて要素サイズの調整を行います。
例えば、ある要素に`width: 500px`を指定し、あわせて`padding: 0 50px`と`border: 5px solid #fff`を指定すると、横幅は500 + 50×2 + 5×2で`合計610px`になります。
これでは、横幅500pxのつもりでレイアウトを作成したとき、表示が崩れてしまいます。

対策として下記のように記述します！

```css:app/assets/stylesheets/application.css
 * {
  box-sizing: border-box;
}
```

これで、paddingやborderの設定を行っても、要素の大きさはwidthやheightで指定したサイズのまま変わらなくなります。

# ルーティングの設定 

一通り準備は出来たので、アプリの実装を行っていきます！
まずはルーティングの設定を行います。 

```ruby:config/routes.rb
Rails.application.routes.draw do
  root to: 'posts#index'
  resources :posts, only: :index
end
```

# コントローラーの作成

続いてコントローラーの作成です！

```ruby:ターミナル
rails g controller posts
```
`rails g controller コントローラー名`でコントローラーが作成できます。
rails gのgは、generateの略で、生成するという意味です。
注意点としてコントローラー名は必ず複数系にすること!

# モデルの作成

```ruby:ターミナル
rails g model post
```

`rails g model モデル名`でモデルが作成できます。
モデル名は単数形にしましょう！

```ruby:db/migrate/20xxxxxx_create_posts.rb
class CreatePosts < ActiveRecord::Migration[6.0]
  def change
    create_table :posts do |t|
      t.text :memo
      t.timestamps
    end
  end
end
```

マイグレーションファイルに、必要なカラム名の記述をします。

```:ターミナル
rails db:migrate
```

記述したら、マイグレーションを実行しましょう！

# 投稿一覧の表示

投稿一覧を表示させるため、コントローラーに記述を追加します。
`Post.all`で投稿されたデータを取得します！

```ruby:app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @posts = Post.all
  end
end
```

```:app/views/posts/index.html.erb
<% @posts.each do |post| %>
  <%= post.memo %>
  <%= post.created_at %>
<% end %>
```

`eachメソッド`で投稿内容を表示させます！

# 投稿ページの実装

一覧ページ実装と同様に投稿機能も実装していきます！

```ruby:config/routes.rb
Rails.application.routes.draw do
  resources :posts, only: [:index, :new]
end
```

```ruby:app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @posts = Post.all
  end

  def new
    @post = Post.new
  end

  def create
    post = Post.create(post_params)
    if post.save
      redirect_to root_path
    else
      render :new
    end
  end

  private
  def post_params
    params.require(:post).permit(:memo)
  end
end
```

```ruby:app/models/posts.rb
class Post < ApplicationRecord
  validates :memo, presence: true
end
```

```:app/views/posts/index.html.erb
<%= link_to "投稿ページ", new_post_path %>
<% @posts.each do |post|%>
  <%= post.memo %>
  <%= post.created_at %>
<% end %>
```

```:app/views/posts/new.html.erb
<h1>投稿ページ</h1>
<%= form_with model: @post, local: true do |form| %>
  <%= form.text_area :memo, placeholder: "memo", rows: "10" %>
  <%= form.submit "投稿する" %>
<% end %>
```

```:app/views/posts/create.html.erb
<h1>投稿が完了しました</h1>
<%= link_to "トップページへ戻る", root_path %>
```

# 最終確認

投稿一覧ページから新規投稿ページへいき、新規投稿してみましょう！
投稿一覧ページへ戻り、投稿内容が表示されていれば成功です！

# 最後に

以上で実装完了です！
今回はCSSを編集していないため、簡素なものになっています。必要に応じて各自編集してください。
では。