第2章
第1章では、AWS Cloud9でRubyを使うための環境構築、Githubにリモートプッシュ、Herokuにデプロイを行った。
第2章では、scaffoldというスクリプトを使って簡単にCRUD機能を持ったアプリケーションを作成する。また、RESTアーキテクチャについて触れていく。
Toy_app
・流れ
toy_app作成→Gemfile設定→gemインストール→Git管理下に配置→リモートレポジトリにプッシュ
①先ずは、新たにtoy_appアプリを生成
$ cd ~/environment
$ rails _6.0.3_ new toy_app ←railsチュートリアルは基本的にバージョン指定
$ cd toy_app/
②Gemfileを設定する。
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem 'rails', '6.0.3'
gem 'puma', '4.3.6'
gem 'sass-rails', '5.1.0'
gem 'webpacker', '4.0.7'
gem 'turbolinks', '5.2.0'
gem 'jbuilder', '2.9.1'
gem 'bootsnap', '1.4.5', require: false
group :development, :test do
gem 'sqlite3', '1.4.1'
gem 'byebug', '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
gem 'web-console', '4.0.1'
gem 'listen', '3.1.5'
gem 'spring', '2.1.0'
gem 'spring-watcher-listen', '2.0.1'
end
group :test do
gem 'capybara', '3.28.0'
gem 'selenium-webdriver', '3.142.4'
gem 'webdrivers', '4.1.2'
end
group :production do
gem 'pg', '1.1.4'
end
# Windows ではタイムゾーン情報用の tzinfo-data gem を含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
railsチュートリアルをしているとGemfileというファイルをよく使います。
Q:Gemfileとは?
A:gemの一覧を記載しているファイルのこと。因みにgemはrubyのライブラリのこと
③gemのインストール
$ bundle install --without production
--without productionとすることで本番環境を除いたgemをインストールできる。
④Toy_appをGitのバージョン管理下に置く。
$ git init
$ git add -A
$ git commit -m "Initialize repository"
⑤リモートリポジトリにプッシュ
$ git remote add origin https://github.com/<あなたのGitHubアカウント名>/toy_app.git
$ git push -u origin master
ここまで出来れば準備完了。
第1章と同様にhello worldと表示する。
・コントローラーとアクションの設定
class ApplicationController < ActionController::Base
def hello
render html: "hello, world!"
end
end
MVCのViewはどこ?
MVCのViewはどこかという話ですが、render html: "hello, world!"の箇所でrenderメソッドを使って描画しています。(本来ならば、Viewファイルを作って呼び出します。)
・ルートルーティングの設定
Rails.application.routes.draw do
root 'application#hello'
end
・変更のコミットは、Heroku&Githubにプッシュ
$ git commit -am "Add hello"
$ heroku create
$ git push && git push heroku master
git push && git push heroku masterの一文について、**&&という箇所があるが、&&**で連結すると一つ目のコマンドが成功した場合に限り実行される。
なので、この場合はgithubへのプッシュが出来たら、herokuにもプッシュするということ。
usersモデル
・users → テーブル名(テーブル名は複数形を使うのが慣例)
・id:integer → 一意のid(数字のダブりがない。整数型)
・name:string → 名前(文字列型)
・email:string → 電子メール(文字列型)
id、name、emailは属性と呼びカラム(column)に相当
カラムとレコードのお話
カラム(column)は列で、レコード(record)は行と言われますが、どちらが縦で横か昔はごっちゃになった事があったので記載。
columnやlineといった単語にl(エル)が含まれてますね。そう、こっちが縦です。(日本語だと列)
recordやrowは、rがありますね。Rは横向きに線が生えていますね。(無理やりですが)。こっちが横です。(日本語だと行)
片方覚えればいいと思います。
micropostsモデル
user_idというのがあるが、これは、usersモデルのidと後で結びつく。
stringとtextのお話
ちょうざっくり説明します。
string型 255文字まで
text型 それ以上
usersリソース
上記でusersテーブルがいきなり出てきたが、ここからscaffoldを使って、同時にusersテーブルも作成していく。
以下scaffoldコマンド
$ rails generate scaffold User name:string email:string
scaffoldの後にUserと入力後、name:stringとemail:stringを追記する。
Q:scaffoldの後のUserはなぜ複数形じゃない?
A:scaffoldの後のUserはモデル名のため単数形を使用する。
できたらデータベースをマイグレートする。
$ rails db:migrate
データベースマイグレートをすることで、データベースを更新しusersデータモデルを作成するため。
ユーザーページ
scaffoldを使ったことで簡単なCRUD機能を持ったページが作られている。
CRUD:CREATE(作成)/READ(読み取り)/UPDATE(更新)/DELETE(削除)
scaffoldでCRUD機能が実装できた。
(scaffoldは便利ですが、未知数の部分が多いので、基本的に使用せず1からCRUDを作っていきます)
MVCの動き
MVCの詳しい動作について解説
1.ブラウザから「/users」というURLのリクエストをRailsサーバーに送信する。
2.「/users」リクエストは、Railsのルーティング機構(ルーター)によってUsersコントローラ内のindexアクションに割り当てられる。
3.ndexアクションが実行され、そこからUserモデルに、「すべてのユーザーを取り出せ」(User.all)と問い合わせる。
4.Userモデルは問い合わせを受け、すべてのユーザーをデータベースから取り出す。
5.データベースから取り出したユーザーの一覧をUserモデルからコントローラに返す。
6.Usersコントローラは、ユーザーの一覧を@users変数(@はRubyのインスタンス変数を表す)に保存し、indexビューに渡す。
7.indexビューが起動し、ERB(Embedded RuBy: ビューのHTMLに埋め込まれているRubyコード)を実行して HTMLを生成(レンダリング)する。
8.コントローラは、ビューで生成されたHTMLを受け取り、ブラウザに返す5
railsチュートリアルから引用
・resources :usersとroot 'users#index'を設定
Rails.application.routes.draw do
resources :users
root 'users#index'
end
resources :usersは、第4章で触れるので、ここではスルー
root 'users#index'は、コントローラー名#アクション名で、usersコントローラーのindexアクションを実行する。
ではusersコントローラーのindexアクションの中身はどうなっているか?は下記のコード(一部省略)
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
@users = User.all
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
@user = User.new
end
# GET /users/1/edit
def edit
end
まずは、indexアクションの動作について解説。
@users = User.allは、Userモデルにある全レコードを取得し、@usersに代入するという意味。なおメソッドにおける変数の定義には、@を付けて@usersのような形でインスタンス変数を定義できる。
インスタンスの簡単な説明
インスタンスは、クラスから生成されたオブジェクトの事。
クラスはインスタンスの型を作るためのもの。
プログラミングの本とか読んでいると、「クラスは、クッキー(お菓子の方)の型を取る道具で、実際に型取られたクッキーがインスタンス!」だとか、「クラスは、自動車の設計図で、それを元に作られた車がインスタンス」とかそんな説明が書いてあります。
次いで、UsersController内には、様々なアクションがあると思いますが、これらはscaffoldで作成されたもの。
第二章はRESTアーキテクチャの概念についての理解があったので、ここで記載する。
Q:REST(レスト)って?
A:REpresentational State Transferの略。既に幅広く普及したWEBの仕組み(HTTPとか)をそのまま利用して、容易にWEBサービスを可能にするもの。
@users変数に全ユーザーが格納されたら、今度はビューを呼び出す。Railsのコントローラー内でインスタンス変数を宣言したことで、この変数はビューでも使えるようになる。
<% @users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.email %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete,
data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
1行目に@usersなるものがあることがわかる。railsチュートリアルでは、このコードの説明は省略しているが、少し説明を加えます。
@usersに格納されたユーザーに関わるデータを一人ずつ|user|に代入して、各ユーザーの名前やメールアドレスを表示するというものです。この作業を人数分繰り返すという訳です。
Usersリソースの欠点
scaffoldという便利な機能がありますが、問題点があります。
・データ検証がされない
→ユーザ名が空白でも、メールアドレスが適当でも通ってしまう。
・ユーザー認証がない
→誰でも制限なしに操作できる。
・テストがない
→必要なレベルのテストまでは書かれていない。
・レイアウトやスタイルが整ってない
→なんかかっこよくない。
・理解が困難
→scaffoldは自動であるがゆえに、コード理解が難しい。
Micropostsリソース
Usersリソースと同様にMicropostsリソースも作成
$ rails generate scaffold Micropost content:text user_id:integer
データベースの更新
$ rails db:migrate
ルーティングの確認
Rails.application.routes.draw do
resources :microposts
resources :users
root 'users#index'
end
resources :micropostsがscaffoldで自動で追加され、これにより各アクションに対応するようになる。

参照:railsチュートリアル
次いで、microposts_controllerの中身も確認(一部省略)
class MicropostsController < ApplicationController
before_action :set_micropost, only: [:show, :edit, :update, :destroy]
# GET /microposts
# GET /microposts.json
def index
@microposts = Micropost.all
end
# GET /microposts/1
# GET /microposts/1.json
def show
end
# GET /microposts/new
def new
@micropost = Micropost.new
end
# GET /microposts/1/edit
def edit
end
UsersControllerの中身と同じであることが分かる。
マイクロポストに制限
現在は投稿する際の文字制限がない。なので、文字数制限を与えてみる。
railsでは、バリデーションという機能を使うことで様々制限を加えられる。
class Micropost < ApplicationRecord
validates :content, length: { maximum: 140 }
end
このコードは、直感的に見た通りの動作をする。コンテンツの最大長さが140文字という内容をそのまま解釈できる。
コードを実装したので、実際に141以上打ち込んでみると、、、

データモデル同士の関連付け
ユーザーモデルとマイクロポストモデルを関連付ける。
class User < ApplicationRecord
has_many :microposts
end
class Micropost < ApplicationRecord
belongs_to :user
validates :content, length: { maximum: 140 }
end
・ユーザーモデルは、沢山のマイクロポストを持っているため、has_manyな関係
・マイクロポストはあるユーザーのみに属しているので、belongs_toの関係
①rails console起動
ubuntu:~/environment/toy_app (master) $ rails console
Running via Spring preloader in process 9488
Loading development environment (Rails 6.0.3)
②最初のユーザーを取得し、first_userに格納
2.6.3 :001 > first_user = User.first
(0.4ms) SELECT sqlite_version(*)
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "名前あり", email: "名前ありメール", created_at: "2021-05-17 22:43:11", updated_at: "2021-05-17 22:44:23">
③first_userに紐づいたマイクロポストを取得
2.6.3 :002 > first_user.microposts
Micropost Load (0.1ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? LIMIT ? [["user_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Micropost id: 1, content: "すっごい眠い", user_id: 1, created_at: "2021-05-18 22:31:59", updated_at: "2021-05-18 22:31:59">]>
④first_userの最初のマイクロポスト(microoist id:1)をmicropostに代入
2.6.3 :003 > micropost = first_user.microposts.first
Micropost Load (0.2ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."id" ASC LIMIT ? [["user_id", 1], ["LIMIT", 1]]
=> #<Micropost id: 1, content: "すっごい眠い", user_id: 1, created_at: "2021-05-18 22:31:59", updated_at: "2021-05-18 22:31:59">
⑤mircropost.userでUser idが1の人の情報を表示
2.6.3 :004 > micropost.user
=> #<User id: 1, name: "名前あり", email: "名前ありメール", created_at: "2021-05-17 22:43:11", updated_at: "2021-05-17 22:44:23">
has_manyとbelong_toを使うことでそれぞれ違ったモデルを結び付けてデータを表示することが出来る。
継承
railsチュートリアル的に、ここは何となくの理解でもOK
ざっくりと説明
Q:継承って?
A:モデルに親子関係があるよ!子は親のクラスを引き継いで、使用できる。親のできることが、子にもできるようになること。
Rubyでは、継承関係を<で表す。
class User < ApplicationRecord
class Micropost < ApplicationRecord
UserとMicropostはApplicationRecordを継承しており、ApplicationRecordはActiveRecord::Baseを継承している。
このような継承関係は、モデルだけではなくコントローラーも同様である。
class UsersController < ApplicationController
class MicropostsController < ApplicationController
ApplicationControllerは、ActionController::Baseを継承
class ApplicationController < ActionController::Base
継承機能が備わっている事で、子クラスでも親クラスで定義しているルールが適用される。そのため、よく使う共通のルールは、親クラスに作成すると良いって話。
演習の内容確認
1つ目
class ApplicationController < ActionController::Base
def hello
render html: "hello, world!"
end
end
2つ目
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
デプロイ
第2章の内容をデプロイ
$ git status #追加の前にこうやって状態を確認するのはよい習慣です
$ git add -A
$ git commit -m "Finish toy app"
$ git push
Gitコミットはこまめにしておくと良いとのこと。
$ git push heroku
herokuにもpushして出来たら完了
おわりに
第二章で学んだ事
・scaffoldでCRUD機能を作った
・MVCの挙動
・UserリソースとMicropostリソースの結びつけ
・継承関係
第二章までは、ほぼ自動的にCRUDの機能を作ってきましたが、これからは自分でやるため段々と難しくなってきます。















