oto-tanblog Written by oto-tan

【Progate】Ruby on Rails5 学習コース総まとめ【復習用】

Ruby

こんにちは!
おとーたんです。

ProgateのRuby on Rails5 学習コースが一通り完了したので、復習用にまとめます。

  • ProgateのRuby on Rails5 学習コースの総まとめ

【Progate】Ruby on Rails5 学習コースで作れるもの

【Progate】Ruby on Rails5 学習コース総まとめ【復習用】

作れるのはTwitterのような投稿型のWebアプリ。

  • 新規投稿
  • 投稿の編集
  • 投稿の削除
  • 投稿の一覧表示(全体/ユーザー)
  • ユーザーの新規登録
  • ユーザー情報の編集
  • ユーザー一覧表示
  • ログイン
  • ログアウト
  • いいね!ボタン
  • いいね!取り消し
  • いいね!した投稿一覧

が行えます。

ディレクトリ構成


tweet_aap
├── app
│   ├── assets
│   │   ├── config
│   │   │   └── manifest.js
│   │   ├── images
│   │   ├── javascripts
│   │   │   └── application.js
│   │   └── stylesheets
│   │       ├── application.css
│   │       ├── home.scss
│   │       ├── posts.scss
│   │       └── users.scss
│   ├── controllers
│   │   ├── concerns
│   │   ├── application_controller.rb
│   │   ├── home_controller.rb
│   │   ├── likes_controller.rb
│   │   ├── posts_controller.rb
│   │   └── users_controller.rb
│   ├── helpers
│   │   └── application_helper.rb
│   ├── jobs
│   │   └── application_job.rb
│   ├── mailers
│   │   └── application_mailer.rb
│   ├── models
│   │   ├── concerns
│   │   ├── application_record.rb
│   │   ├── like.rb
│   │   ├── post.rb
│   │   └── user.rb
│   └── views
│       ├── home
│       │   ├── about.html.erb
│       │   └── top.html.erb
│       ├── layouts
│       │   ├── application.html.erb
│       │   ├── mailer.html.erb
│       │   └── mailer.html.erb
│       ├── posts
│       │   ├── edit.html.erb
│       │   ├── index.html.erb
│       │   ├── new.html.erb
│       │   └── show.html.erb
│       └── users
│           ├── edit.html.erb
│           ├── index.html.erb
│           ├── likes.html.erb
│           ├── login_form.html.erb
│           ├── new.html.erb
│           └── show.html.erb
├── bin
│   ├── bundle
│   ├── rails
│   ├── rake
│   ├── setup
│   └── update
├── config
│   ├── environments
│   ├── initializers
│   ├── locales
│   ├── application.rb
│   ├── boot.rb
│   ├── database.yml
│   ├── environment.rb
│   ├── puma.rb
│   ├── routes.rb
│   ├── secrets.yml
│   └── spring.rb
├── db
│   ├── migrate
│   │   ├── XXXXXXXXXXXXXX_create_posts.rb
│   │   ├── XXXXXXXXXXXXXX_create_users.rb
│   │   ├── XXXXXXXXXXXXXX_add_image_name_to_users.rb
│   │   ├── XXXXXXXXXXXXXX_add_password_to_users.rb
│   │   ├── XXXXXXXXXXXXXX_add_user_id_to_posts.rb
│   │   ├── XXXXXXXXXXXXXX_create_likes.rb
│   │   └── XXXXXXXXXXXXXX_change_users_columns.rb
│   ├── development.sqlite3
│   ├── schema.rb
│   └── seeds.rb
├── lib
├── public
├── vendor
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
└── config.ru

config

設定に関するファイルが配置されているディレクトリ。

routes.rb

Webアプリ内のルーティングを設定するファイル。


Rails.application.routes.draw do
	# TOPページを localhost:3000 で接続できるようにするには「/」のみにする
	get "/" => "home#top"
	# 対応するルーティングとアクションを追加
	# 以下場合だと views/home/about.html.erb に about アクションを追加
	get "about" => "home#about"

	get "posts/index" => "posts#index"
	get "posts/new" => "posts#new"
	# 「posts/:〇〇」のルーティングは「posts/〇〇」のルーティングより下に書く
	get "posts/:id" => "posts#show"
	# フォームの値を受け取る場合は「post」とする必要がある
	post "posts/create" => "posts#create"
	# posts/:id/edit というように「:id」を間にいれることもできる
	get "posts/:id/edit" => "posts#edit"
	post "posts/:id/update" => "posts#update"
	post "posts/:id/destroy" => "posts#destroy"

	post "users/:id/update" => "users#update"
	get "users/:id/edit" => "users#edit"
	post "users/create" => "users#create"
	get "signup" => "users#new"
	get "users/index" => "users#index"
	get "users/:id" => "users#show"
	post "login" => "users#login"
	post "logout" => "users#logout"
	get "login" => "users#login_form"
	get "users/:id/likes" => "users#likes"

	post "likes/:post_id/create" => "likes#create"
	post "likes/:post_id/destroy" => "likes#destroy"
end

画面遷移するルーティングを


get "URL" => "コントローラー名#アクション名"

または


post "URL" => "コントローラー名#アクション名"

で作成する。

  • getはデータ取得
  • postはデータ更新

同じルーティングでも get と post では別のルーティングとして扱われるので、例えば


get "posts/new" => "posts#new"
post "posts/new" => "posts#new"

と書いても、別のルーティング扱いになる。

接続方法は


get "posts/index" => "posts#index"

のルーティングであれば「localhost:3000/posts/index」で接続可能。


get "index" => "posts#index"

にすると「localhost:3000/index」で接続可能になる。
(先頭にスラッシュをつけない)

posts/:id というように「/:〇〇」を使うことで、各ユーザーごとの詳細画面を表示させるにルーティングも作れる。
しかし、ルーティングは合致するURLを上から順に探すため


get posts/:〇〇

のルーティングは


get posts/〇〇

のルーティングより下に書かないと、「localhost:3000/posts/〇〇」というURLで接続した時に


get posts/:〇〇

というルーティングに合致してしまうため注意!

app/controllers

コントローラーは、各ページの処理を記述する。
TOPページに関するHomeControllerや投稿ページに関するPostsControllerなど、それぞれの役割に対して1つ作成する。
コントローラ内のメソッドを「アクション」と呼び、コントローラと同名のviewフォルダから、アクションと同じ名前のHTMLファイルを探してブラウザに返す。

topアクションの場合


views/home/top.html.erb

を探す。


rails generate controller コントローラー名 アクション名

でビューも含めて自動で作成される。


# コントローラ名
class HomeController < ApplicationController
	before_action :forbid_login_user, {only: [:top]}

	# アクション名
	def top
	end

	def about
	end
end

ビューが必要ない場合は、直接ファイルを作成すればOK。

作成したコントローラーは必ず「application_controller.rb」を継承するようにしておく。

posts_controller.rb


# 投稿処理を管理するコントローラー
# application_controller.rb を継承
class PostsController < ApplicationController
	# ログインしているかどうかをチェックするための共通処理を呼び出す
	before_action :authenticate_user
	before_action :ensure_correct_user, {only: [:edit, :update, :destroy]}

	def index
		# 変数に「@」をつけることで、変数をビューで使用することができる
		# モデル名.all とすることで、全てのデータを取得でき
		# モデル名.all.order(カラム名: 並び替えの順序)とすることで、昇順降順でデータを取得できる(:ascか:desc)
		@posts = Post.all.order(created_at: :desc)
	end

	def show
		# ルーティングの「posts/:id」から渡されるidは、paramsという変数の中のハッシュとして入っている
		# params[:id]とすることでルーティングの「posts/:id」からidの値を取得することができる
		# find_byメソッドを使用すると モデル名.find_by(カラム名: 値) でその値を持ったデータを取得できる
		@post = Post.find_by(id: params[:id])
		# @user = User.find_by(id: params[:id]) としてもいいが
		# postインスタンスから呼び出しておくようにしておけば、効率のいい書き方ができる(post.rb 参照)
		@user = @post.user
		# countメソッドを使用することで、データの件数を取得できる
		@likes_count = Like.where(post_id: @post.id).count
	end

	def new
		# バリデーションエラー時に localhost:3000/posts/new 経由でアクセスするとエラーになるため
		# @post に Post.new を代入しておく
		@post = Post.new
	end

	def create
		# Post.new(カラム名: 値, カラム名: 値, ...)でインスタンスを生成、変数.saveでDBに登録できる
		@post = Post.new(
			# params変数はフォームのname属性の値を受け取ることも可能
			# params[:〇〇]でname属性が〇〇の値を受け取れる
			# この場合、name属性がcontentの値を受け取れる
			content: params[:content],
			# 現在ログイン中のユーザーIDを登録しておくことで、どのユーザーが投稿したかわかるようにしておく
			user_id: @current_user.id
		)
		# 変数.saveが成功するとtrue、失敗するとfalseを返す(バリデーションにかかるとfalse)
		if @post.save
			flash[:notice] = "投稿を作成しました"
			# redirect_to(URL)で、そのページにリダイレクトできる
			redirect_to("/posts/index")
		else
			# redirect_to(URL) で編集画面に遷移すると、入力値がリセットされてしまうが
			# render("フォルダ名/ファイル名") を使用すると、入力した値が引き継がれまま遷移できる
			# redirect_to がURLを指定するのに対し、render はディレクトリとファイルを指定する(ルーティングの指定と一緒)
			render("posts/new")
		end
	end

	def edit
		@post = Post.find_by(id: params[:id])
	end

	def update
		# id と一致するデータを取得
		@post = Post.find_by(id: params[:id])
		# 編集画面から受け取った値(つぶやき)を代入するとDB内の値を更新できる
		@post.content = params[:content]
		# @post.save で更新内容を保存
		if @post.save
			# flash[:notice]に文字列を代入すると、変数flash[:notice]をビューで使うことができる
			# 変数flashの内容は1度表示されたら自動で削除される
			flash[:notice] = "投稿を編集しました"
			redirect_to("/posts/index")
		else
			render("posts/edit")
		end
	end

	def destroy
		# id と一致するデータを取得
		@post = Post.find_by(id: params[:id])
		# 変数.destroyでデータを削除
		@post.destroy
		flash[:notice] = "投稿を削除しました"
		redirect_to("/posts/index")
	end

	# 投稿内容を編集できてしまうため、投稿に紐づくユーザーと現在ログインしているユーザーが異なるかどうかを比べる
	def ensure_correct_user
		@post = Post.find_by(id: params[:id])
		if @post.user_id != @current_user.id
			flash[:notice] = "権限がありません"
			redirect_to("/posts/index")
		end
	end

end

application_controller.rb


# 全てのコントローラーで共通する処理は application_controller.rb に記述する
class ApplicationController < ActionController::Base
	# before_action :メソッド名 を利用することで、全アクションで必ず呼び出されるようになる
	# この場合、ユーザーのログイン情報を取得するためのset_current_userメソッドを必ず呼び出すようにしている
	before_action :set_current_user

	def set_current_user
		@current_user = User.find_by(id: session[:user_id])
	end

	# 投稿画面や編集画面のURLを直接入力するとアクセスできてしまうので
	# ログインしていない状態の場合はログイン画面にリダイレクトする共通処理を用意しておく
	def authenticate_user
		# @変数は同じクラスの異なるメソッドで共通して使用することが可能
		if @current_user == nil
			flash[:notice] = "ログインが必要です"
			redirect_to("/login")
		end
	end

	# 新規登録画面やログイン画面のURLを直接入力するとアクセスできてしまうので
	# ログインしている状態の場合は投稿一覧画面にリダイレクトする共通処理を用意しておく
	def forbid_login_user
		if @current_user
			flash[:notice] = "すでにログインしています"
			redirect_to("/posts/index")
		end
	end

end

users_controller.rb


# ユーザー処理を管理するコントローラー
class UsersController < ApplicationController
	# before_action :メソッド名, {only: [:アクション名, :アクション名,...]} とすることで
	# 指定したアクションのみにメソッドを実行できる
	before_action :authenticate_user, {only: [:index, :show, :edit, :update]}
	before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}
	before_action :ensure_correct_user, {only: [:edit, :update]}

	def index
		@users = User.all
	end

	def show
		@user = User.find_by(id: params[:id])
	end

	def new
		@user = User.new
	end

	def create
		@user = User.new(
			name: params[:name],
			email: params[:email],
			# ファイル名を入れることで、詳細画面や一覧画面で表示することが可能
			image_name: "default_user.jpg",
			# password_digestカラム追加後も、has_secure_passwordでハッシュ化されたパスワードが自動的に保存されるため
			# passwordに関するコードを変更する必要はない
			password: params[:password]
		)
		if @user.save
			session[:user_id] = @user.id
			flash[:notice] = "ユーザー登録が完了しました"
			redirect_to("/users/#{@user.id}")
		else
			render("users/new")
		end
	end

	def edit
		@user = User.find_by(id: params[:id])
	end

	def update
		@user = User.find_by(id: params[:id])
		@user.name = params[:name]
		@user.email = params[:email]
		# if params[:〇〇]でフォームから値を受け取ったかどうかをジャッジできる
		if params[:image]
			# ユーザーIDをファイル名にする
			@user.image_name = "#{@user.id}.jpg"
			image = params[:image]
			# ファイルを作成するにはFileクラスの File.write(ファイルの場所, ファイルの中身) を使用する
			# 画像の場合は特殊なので File.binwrite(ファイルの場所, ファイルの中身) を使用する必要がある
			# 画像を取得した変数 image に対して read メソッドを利用することで画像を取得できる
			File.binwrite("public/user_images/#{@user.image_name}", image.read)
		end

		if @user.save
			flash[:notice] = "ユーザー情報を編集しました"
			redirect_to("/users/#{@user.id}")
		else
			render("users/edit")
		end
	end

	def login_form
	end

	def login
		@user = User.find_by(email: params[:email])
		# has_secure_passwordメソッドを有効にすると、渡された引数をハッシュ化し
		# password_digestの値と一致するかどうかを判定してくれる authenticateメソッドを使えるようになる
		if @user && @user.authenticate(params[:password])
			# session変数を利用すると、ブラウザに情報が保存され、ページを移動しても保存した値を取得できるようになる
			# session[:キー名] = 値 で保存が可能
			session[:user_id] = @user.id
			flash[:notice] = "ログインしました"
			redirect_to("/posts/index")
		else
			@error_message = "メールアドレスまたはパスワードが間違っています"
			@email = params[:email]
			@password = params[:password]
			render("users/login_form")
		end
	end

	def logout
		# ログアウトすると、ユーザーのsession情報は必要なくなるため、nilで値を空にする
		session[:user_id] = nil
		flash[:notice] = "ログアウトしました"
		redirect_to("/login")
	end

	def likes
		@user = User.find_by(id: params[:id])
		@likes = Like.where(user_id: @user.id)
	end

	# URLを直接入力したときのチェック処理
	def ensure_correct_user
		# params[:id]で取得できる値は文字列のため、数値の @current_user.id と比較しても必ずfalseとなる
		# to_iメソッドを利用して params[:◯◯].to_i とすることで数値に変換できる
		if @current_user.id != params[:id].to_i
			flash[:notice] = "権限がありません"
			redirect_to("/posts/index")
		end
	end

end

likes_controller.rb


# いいね!処理を管理するコントローラー
class LikesController < ApplicationController
	before_action :authenticate_user

	def create
		# 投稿に対していいね!したユーザーを登録
		@like = Like.new(
			user_id: @current_user.id,
			post_id: params[:post_id]
		)
		@like.save
		redirect_to("/posts/#{params[:post_id]}")
	end

	def destroy
		# 投稿に対していいね!を取り消したしたユーザーを検索して削除
		@like = Like.find_by(
			user_id: @current_user.id,
			post_id: params[:post_id]
		)
		@like.destroy
		redirect_to("/posts/#{params[:post_id]}")
	end

end

app/models


rails g model モデル名 カラム名:型

で生成されるマイグレーションファイルと同時に model にもテーブル名と同名のファイルが作成される

post.rb


class Post < ApplicationRecord
	# validates :検証するカラム名, {presence: true} で値が空かどうかをチェックしてくれる
	validates :user_id, {presence: true}
	# length: {maximum: 140} で値の最大文字数をチェックできる
	validates :content, {presence: true, length: {maximum: 140}}

	def user
		# userインスタンスを返すことで、postインスタンスを取得した時に使えるようになる
		return User.find_by(id: self.user_id)
	end

end

validates :検証するカラム名, { 検証する内容 }

データを保存する前にチェックできる(バリデーション)。

複数チェックしたい場合は


validates :検証するカラム名, { 検証する内容, 検証する内容 }

というように「,(カンマ)」で区切ると複数チェックが可能

user.rb


class User < ApplicationRecord
	# has_secure_passwordメソッドでパスワードを自動でハッシュ化する
	has_secure_password

	validates :name, {presence: true}
	validates :email, {presence: true, uniqueness: true}

	def posts
		# 複数のデータを取得するにはfind_byメソッドではなくwhereメソッドを使用する
		# 条件に一致するデータが配列で取得可能
		return Post.where(user_id: self.id)
	end

end

Gemfileに「bcrypt」をインストールすることで、「has_secure_password」というパスワードを自動でハッシュ化してくれるメソッドが使える

Gemfile

Gemはすでに出来上がっている機能をパッケージ化したもの。

今回はパスワードを覗き見されても大丈夫なように、ハッシュ化できる「bcrypt」というGemをインストール。


source 'https://rubygems.org'

gem 'rails', '5.0.3'
# Use Puma as the app server
gem 'puma', '3.6.2'
# Use SCSS for stylesheets
gem 'sass-rails', '5.0.6'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '3.0.4'
gem 'pry-rails', '0.3.4'
# Use jquery as the JavaScript library
gem 'jquery-rails', '4.2.2'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '5.0.1'

# ハッシュ化できる gem
gem 'bcrypt'

group :development, :test do
	gem 'sqlite3', '1.3.13'
	gem 'byebug', '9.0.6', platform: :mri

	gem 'web-console', '3.4.0'
	gem 'listen', '3.0.8'
	# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
	gem 'spring', '2.0.1'
	gem 'spring-watcher-listen', '2.0.1'
end

gem は


gem 'gemの名前', 'gemのバージョン'

とすることでインストール可能。
「gemのバージョン」部分を指定しない場合は最新のバージョンがインストールされる。

Gemfileに記載したら


bundle install

でGemをインストールできる。

like.rb


class Like < ApplicationRecord
	validates :user_id, {presence: true}
	validates :post_id, {presence: true}
end

app/views/home

top.html.erb


<div class="main top-main">
	<div class="top-message">
		<h2>つぶやきで、世界はつながる</h2>
		<p>今の気持ちをつぶやいてみよう!</p>
	</div>
</div>

about.html.erb


<div class="about-main">
	<h2>TweetAppとは</h2>
	<p>
		SNSサービスです。
		近況やつぶやきを投稿し、他のユーザーと楽しくコミュニケーションできます。
	</p>
	<!-- 画像が配置されているディレクトリを記述 -->
	<img class="about-img" src="/tweets.png">
</div>

画像を表示させるときは、必ず先頭に「/(スラッシュ)」をつける
CSS内で画像を指定する場合も同様。


body {
	/* 必ず先頭に「/」をつける */
	background-image: url("/top.jpg");
}

app/views/layouts

application.html.erb

application.html.erbは全アクションから呼び出されるため、共通で表示したい内容はここに記述する


<!DOCTYPE html>
<html>
<head>
	<title>TweetApp</title>
	<%= csrf_meta_tags %>

	<%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
	<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
	<!-- Font Awesomeの読み込み -->
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
	<header>
		<div class="header-logo">
			<% if @current_user %>
			<!-- link_to("リンクしたい文字", "リンク先") とすることで、リンク先に遷移できる -->
			<%= link_to("TweetApp", "/posts/index") %>
			<% else %>
			<%= link_to("TweetApp", "/") %>
			<% end %>
		</div>
		<ul class="header-menus">
			<!-- ログインしているかどうかでメニューの表示を切り替える -->
			<% if @current_user %>
			<li>
				<%= link_to(@current_user.name, "/users/#{@current_user.id}") %>
			</li>
			<li>
				<%= link_to("投稿一覧", "/posts/index") %>
			</li>
			<li>
				<%= link_to("新規投稿", "/posts/new") %>
			</li>
			<li>
				<%= link_to("ユーザー一覧", "/users/index") %>
			</li>
			<li>
				<%= link_to("ログアウト", "/logout", {method: "post"}) %>
			</li>
			<% else %>
			<li>
				<%= link_to("TweetAppとは", "/about") %>
			</li>
			<li>
				<%= link_to("新規登録", "/signup") %>
			</li>
			<li>
				<%= link_to("ログイン", "/login") %>
			</li>
			<% end %>
		</ul>
	</header>
	<!-- controllerでfalsh変数に代入されている場合は、falshを表示させる -->
	<% if flash[:notice] %>
	<div class="flash">
		<%= flash[:notice] %>
	</div>
	<% end %>
	<!-- 各アクションに対応したビューファイルは yield に代入されている -->
	<%= yield %>
</body>
</html>

app/views/posts

index.html.erb


<div class="main posts-index">
	<div class="container">
		<!-- <% %> を使用してRubyコードをHTMLに埋め込むことができる -->
		<!-- アクション内で定義した「@」付きの変数が使える -->
		<% @posts.each do |post| %>
		<div class="posts-index-item">
			<div class="post-left">
				<!-- 「=」を先頭に入れて <%= %> とすることで、HTML内に出力もできる -->
				<img src="<%= "/user_images/#{post.user.image_name}" %>">
			</div>
			<div class="post-right">
				<div class="post-user-name">
					<!-- 「リンク先」にハッシュを使って変数展開を使用すると、指定した変数に対する遷移先に遷移できる -->
					<%= link_to(post.user.name, "/users/#{post.user.id}") %>
				</div>
				<%= link_to(post.content, "/posts/#{post.id}") %>
			</div>
		</div>
		<% end %>
	</div>
</div>

show.html.erb


<div class="main posts-show">
	<div class="container">
		<div class="posts-show-item">
			<div class="post-user-name">
				<!-- ユーザー画像を表示 -->
				<img src="<%= "/user_images/#{@user.image_name}" %>">
				<!-- ユーザー詳細ページへリンク -->
				<%= link_to(@user.name, "/users/#{@user.id}") %>
			</div>
			<p>
				<%= @post.content %>
			</p>
			<div class="post-time">
				<%= @post.created_at %>
			</div>
			<!-- ログインしているユーザーがその投稿にいいねしている場合と、そうでない場合で表示方法を切り替える -->
			<% if Like.find_by(user_id: @current_user.id, post_id: @post.id) %>
				<%= link_to("/likes/#{@post.id}/destroy", {method: "post"}) do %>
				<span class="fa fa-heart like-btn-unlike"></span>
				<% end %>
			<% else %>
				<!-- いいね!ボタンのハートアイコンを表示させる -->
				<!-- link_to("HTMLタグ", "URL") とするとHTMLタグが文字列として表示されてしまうため -->
				<!-- link_to("URL", {method: "post"}) do -->
					<!-- HTMLタグ -->
				<!-- end -->
				<!-- とすることでHTMLタグをタグとして表示できる -->
				<%= link_to("/likes/#{@post.id}/create", {method: "post"}) do %>
					<span class="fa fa-heart like-btn"></span>
				<% end %>
			<% end %>
			<%= @likes_count %>
			<!-- 詳細画面のユーザーとログインユーザーが一致する時のみ「編集」「削除」を表示する -->
			<% if @post.user_id == @current_user.id %>
			<div class="post-menus">
				<%= link_to("編集", "/posts/#{@post.id}/edit") %>
				<!-- postのルーティングを探すようにするため、第三引数に {method: "post"} を指定する -->
				<%= link_to("削除", "/posts/#{@post.id}/destroy", {method: "post"}) %>
			</div>
			<% end %>
		</div>
	</div>
</div>

link_toメソッドは get のルーティングを探してしまうため、post のルーティングを探すように第三引数に {method: “post”} を指定する。

edit.html.erb


<div class="main posts-new">
	<div class="container">
		<h1 class="form-heading">編集する</h1>
		<%= form_tag("/posts/#{@post.id}/update") do %>
		<div class="form">
			<div class="form-body">
				<!-- 変数.errors.full_messages にエラーメッセージの配列が入っている -->
				<% @post.errors.full_messages.each do |message| %>
				<div class="form-error">
					<%= message %>
				</div>
				<% end %>
				<!-- textare 内に<%= 変数 %>を入れておくと初期値として表示できる -->
				<textarea name="content"><%= @post.content %></textarea>
				<input type="submit" value="保存">
			</div>
		</div>
		<% end %>
	</div>
</div>

new.html.erb


<div class="main posts-new">
	<div class="container">
		<h1 class="form-heading">投稿する</h1>
		<!-- form_tagメソッドで「form_tag(送信先のURL) do」とすると指定されたURLにデータが送信される -->
		<%= form_tag("/posts/create") do %>
		<div class="form">
			<div class="form-body">
				<% @post.errors.full_messages.each do |message| %>
				<div class="form-error">
					<%= message %>
				</div>
				<% end %>
				<!-- form_tag内に記述されているので、@post.contentの値が指定されたform_tagの送信先に送信される -->
				<textarea name="content"><%= @post.content %></textarea>
				<input type="submit" value="投稿">
			</div>
		</div>
		<% end %>
	</div>
</div>

app/views/users

index.html.erb


<div class="main users-index">
	<div class="container">
		<h1 class="users-heading">ユーザー一覧</h1>
		<!-- 一覧に画像を表示する場合は、each文を使って表示させる -->
		<% @users.each do |user| %>
		<div class="users-index-item">
			<div class="user-left">
				<img src="<%= "/user_images/#{user.image_name}" %>">
			</div>
			<div class="user-right">
				<%= link_to(user.name, "/users/#{user.id}") %>
			</div>
		</div>
		<% end %>
	</div>
</div>

show.html.erb


<div class="main user-show">
	<div class="container">
		<div class="user">
			<!-- ハッシュをつかって変数が入るようにしておけば、ユーザー毎にの画像を表示可能 -->
			<img src="<%= "/user_images/#{@user.image_name}" %>">
			<h2><%= @user.name %></h2>
			<p><%= @user.email %></p>
			<!-- 詳細画面のユーザーとログインユーザーが一致している場合のみ、編集リンクを表示させる -->
			<% if @user.id == @current_user.id %>
				<%= link_to("編集", "/users/#{@user.id}/edit") %>
			<% end %>
		</div>

		<ul class="user-tabs">
			<li class="active"><%= link_to("投稿", "/users/#{@user.id}") %></li>
			<li><%= link_to("いいね!", "/users/#{@user.id}/likes") %></li>
		</ul>
		<!-- user.rbで取得した投稿内容を表示する -->
		<% @user.posts.each do |post| %>
		<div class="posts-index-item">
			<div class="post-left">
				<img src="<%= "/user_images/#{post.user.image_name}" %>">
			</div>
			<div class="post-right">
				<div class="post-user-name">
					<%= link_to(post.user.name, "/users/#{post.user.id}") %>
				</div>
				<%= link_to(post.content, "/posts/#{post.id}") %>
			</div>
		</div>
		<% end %>
	</div>
</div>

edit.html.erb


<div class="main users-edit">
	<div class="container">
		<div class="form-heading">アカウント編集</div>
		<div class="form users-form">
			<div class="form-body">
				<% @user.errors.full_messages.each do |message| %>
				<div class="form-error">
					<%= message %>
				</div>
				<% end %>
				<!-- 画像の送信は特殊なため、{multipart: true} を第二引数に追加する必要がある -->
				<%= form_tag("/users/#{@user.id}/update", {multipart: true}) do %>
				<p>ユーザー名</p>
				<input name="name" value="<%= @user.name %>">
				<p>画像</p>
				<input name="image" type="file">
				<p>メールアドレス</p>
				<input name="email" value="<%= @user.email %>">
				<input type="submit" value="保存">
				<% end %>
			</div>
		</div>
	</div>
</div>

new.html.erb


<div class="main users-new">
	<div class="container">
		<div class="form-heading">新規ユーザー登録</div>
		<div class="form users-form">
			<div class="form-body">
				<% @user.errors.full_messages.each do |message| %>
				<div class="form-error">
					<%= message %>
				</div>
				<% end %>

				<%= form_tag("/users/create") do %>
				<p>ユーザー名</p>
				<!-- inputタグはvalue属性の中にRubyコードを埋め込むことでコントローラーに値を送れる -->
				<input name="name" value="<%= @user.name %>">
				<p>メールアドレス</p>
				<input name="email" value="<%= @user.email %>">
				<p>パスワード</p>
				<input type="password" name="password" value="<%= @user.password %>">
				<input type="submit" value="新規登録">
				<% end %>
			</div>
		</div>
	</div>
</div>

login_form.html.erb


<div class="main users-new">
	<div class="container">
		<div class="form-heading">ログイン</div>
		<div class="form users-form">
			<div class="form-body">
				<% if @error_message %>
				<div class="form-error">
					<%= @error_message %>
				</div>
				<% end %>

				<%= form_tag("/login") do %>
				<p>メールアドレス</p>
				<input name="email" value="<%= @email %>">
				<p>パスワード</p>
				<!-- type="password" で入力値を伏字にできる -->
				<input type="password" name="password" value="<%= @password %>">
				<input type="submit" value="ログイン">
				<% end %>
			</div>
		</div>
	</div>
</div>

likes.html.erb


<div class="main user-show">
	<div class="container">
		<div class="user">
			<img src="<%= "/user_images/#{@user.image_name}" %>">
			<h2><%= @user.name %></h2>
			<p><%= @user.email %></p>
			<% if @user.id == @current_user.id %>
			<%= link_to("編集", "/users/#{@user.id}/edit") %>
			<% end %>
		</div>

		<ul class="user-tabs">
			<li><%= link_to("投稿", "/users/#{@user.id}") %></li>
			<li class="active"><%= link_to("いいね!", "/users/#{@user.id}/likes") %></li>
		</ul>

		<!-- 変数 like に紐づく投稿を取得する -->
		<% @likes.each do |like| %>
		<% post = Post.find_by(id: like.post_id) %>

		<div class="posts-index-item">
			<div class="post-left">
				<img src="<%= "/user_images/#{post.user.image_name}" %>">
			</div>
			<div class="post-right">
				<div class="post-user-name">
					<%= link_to(post.user.name, "/users/#{post.user.id}") %>
				</div>
				<%= link_to(post.content, "/posts/#{post.id}") %>
			</div>
		</div>
		<% end %>
	</div>
</div>

db/migrate

マイグレーションファイルは


rails g model モデル名 カラム名:型

で自動的に生成されるファイル。
指定したテーブル名は、必ずモデル名に「s」がついた複数形になる。

作成日作成時間_create_posts.rb


class CreatePosts < ActiveRecord::Migration[5.0]
	def change
		create_table :posts do |t|
			# カラム名:型はここに定義される
			t.text :content

			t.timestamps
		end
	end
end

作成日作成時間_add_image_name(以下略)


class AddImageNameToUsers < ActiveRecord::Migration[5.0]
	def change
		# add_column :テーブル名, :カラム名, :データ型 でカラムを追加できる
		# この場合、usersテーブルに image_name カラムを追加
		add_column :users, :image_name, :string
	end
end

「rails g migration ファイル名」でマイグレーションファイルのみ作成可能。
「rails g model」で作成時は、changeメソッド内の処理が自動で記述されるが、「rails g migration」で生成された場合は自分で記述する

作成日作成時間_change_users_columns.rb


class ChangeUsersColumns < ActiveRecord::Migration[5.0]
	def change
		add_column :users, :password_digest, :string
		# カラムを削除する場合は、remove_columnを使用する
		remove_column :users, :password, :string
	end
end

まとめ

以上、ProgateのRuby on Rails5 学習コースの総まとめでした。
完全に自分用ですが、道場コースなどの参考や、復習に使ってください。