超初心者のための「Railsがなにをしているか例えてみよう」講座

#超初心者のための「Railsがなにをしているか例えてみよう」講座　

おはようございます、こんにちは、こんばんわ。
私はインフラトップという会社で、
プログラミング学習の「WEBCAMP」でメンターとして勤めております。
その中で、良くされる質問が、
「Railsでそもそも何を書いたらいいのかわからない」
「Railsがなんで動いているのかわからない」
などです。その気持ち…。
よ～～～～～～～～～～～～っくわかります。

.saveとついているから何となく保存されているんだろうな、
とゲームなどでそれとなく覚えている単語から推測、
理解して使っているような時期が、私にもありました。

WEBCAMPメンターとして働く最中にしたRailsの仕組みの説明を、
フィードバックとして記事にしようと思い立ちました。

プログラミングは、
どう説明しても人によって理解の速度が違うので、
これが「完璧な説明」とは言えないと思います。
しかし生徒の皆様にご理解をいただけたことも多く、
有効な説明と自負しております。

あくまでもわかりやすくするために多少の独自解釈を含みつつ、
ざっくりかいつまんでのお話をさせていただきます。



## もくじ
- そもそもRailsって何をしているの？
- Railsの動きは、「店舗と商品と運送と保存管理」で成り立っている
- Railsで最低限抑えるべきこと


## そもそもRailsって何？何をしているの？
まずはここからご説明をさせていただきます。
Rubyを使って作られたフレームワークということが一般的に説明されていますが、
一言で言えば、

- Railsの規約に従って作っていけば、比較的簡単にアプリを作れる仕組み
- Rubyを使って作られており、アプリの作成にもRubyが使える。
- Web上にアプリ・サービスを作る事に使える。

というのが、Railsフレームワークです。
ひとまず、この３点を覚えておけばRailsの理解の下準備としては十分です。
Web上にアプリケーションを作る、というのがとても重要です。

続いて、Railsが何をしているのかをご説明します。
MVCという構造を採用しています。

- Model…データベースの管理
- View…ホームページとして表示する機能
- Controller…機能を定義して、モデルと提携してデータを引き出し、Viewの管理も行う

というようになっています。

つまり、
Web上にアプリを作るというのは、
フォームに文字などを入れると、データベースに保存され、
自動で更新されるホームページが出来上がる、ということです。

それだけ？と思うかもしれませんが、極論を言えばそれだけです。
その中に数式を入れて計算させたり、
通常のホームページのように装飾したりできますが、
根本の部分はこの点に集約されます。
もっと便利にするためにgemなども使えますが、
こちらは基礎を押さえてからご利用頂いた方がいいと思います。

基本的にはこの点を起点としてRailsアプリは作られている、と考えておきましょう。


## Railsの動きは「店舗と商品と運送と保存管理」で成り立っている

それでは、Railsアプリの基本を押さえる為に、
Railsがしている仕事を現実の仕事に例えていきます。
MVCの説明をしましたが、一つずつ分解して考えていきましょう。

- Model→データベース＝「運送業の倉庫」データを預けたり、預かり方を設定できる。
- View→ホームページ＝「コンビニ店舗」預かったデータをホームページに展開、閲覧できるようにする。新しいデータの預かりもできる。
- Controller→「倉庫の従業員＆運転手」仕事のやり方を作る、データの出し入れの管理＝倉庫の従業員兼、運送トラック。

MVCに加えて、今度はRoutesというのも出て来ます。

- Routes→「倉庫とコンビニの住所」ブラウザでどの住所＝URLに行けば、仕事ができるかを設定する。

まずはこれくらいを意識して、解説を読んでみましょう。
今回はデータベースへの保存と、Viewからのブラウザ表示のみに焦点を当てます。
実際に手を動かしてチェックしてみて下さい。

それでは、スタート前に、以下のコマンドを入れて下準備をします。
コントローラを準備しましょう。
```rails g controller posts new index create show 
```

続いて、routesを変更します。
routesは、

- URLを入力したら
- viewで<%= link_to 'リンク名', ~path %>で作られるリンクをクリックしたら
- フォームなどのデータベースに更新する処理をしたら

どのような機能につながるのかを、
設定します。

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

この場合は、URLにつないだら、コントローラに設定されたデータを持ってきて、
同じ名前のアクション名のついたViewをホームページとして設定します。

post '/モデル名s' => 'モデル名s(コントローラ名）#create'

この場合は、Viewファイルにあるフォームから送信した場合、
モデル名に対応したデータベースに保存させる、という記述です。
createのアクションで詳しく解説します。

それでは今回説明するアクションのroutesを書いていきましょう。

```config/routes.rb
Rails.application.routes.draw do
  # アプリを開いた瞬間につながるページをrootで記述します。
  root 'posts#index'
  
  # 今回使用するrouteはこちらです。
  # resourcesで自動出力されるものと同一にしてあります。
  get  '/posts/new'  => 'posts#new',as: 'new_post'
  post '/posts'      => 'posts#create'
  get  '/posts'      => 'posts#index'
  get  '/posts/:id'  => 'posts#show',as: 'post'
end

```
ここまでで、下準備はOKです。
あとは、実際に起こっている出来事を追いかけながらチェックします。

まずは、データの格納先である、データベースに保存するためのモデルを作ります。
モデルは「データベース」そのものというよりは、
データベースに対応した箱を作り、その取扱い方法を記述するものです。
今回は、データベースに対応した箱を作るコマンドからスタートします。
rails new アプリ名
でアプリを作成後、アプリに移動、その後に実行していきます。
以下のコマンドをターミナルに打ち込んでみましょう。

```
rails g model post title:string body:string
rails db:migrate
```
このコマンドを実行すると、
こんな感じの仕切りが付いた箱が作れるようになります。
今後、posts_controllerでPost.newと入れると、
保存用に準備できる箱ができあがるようになります。
![new.png](https://qiita-image-store.s3.amazonaws.com/0/316335/647dcebd-7d1c-851b-ec9a-81a3483af0fd.png)


そして仕切り箱には名前がついています。

title,body,id,created_at,updated_at

この仕切り箱一つ一つのデータの格納場所を、
「カラム」といいます。
このうち、
titleとbodyは、コマンドで自分で準備したもので、
id,created_at,updated_atの三つは、自動で準備されるものです。
この三つはrailsが自動で記入するので、基本的にはいじれないものです。
idは保存されたデータに順番に自動で振られる番号です。（重要）
created_atはデータの作成日、
updated_atはデータの更新日です。
先ほど入力した
```rails g model post title:string body:string```
というコマンドで、Postモデルが出来あがり、
それ以降は「Post.new」とコントローラで記述することで、
一つ箱が作れるようになります。
これがないと、データをデータベースに保存できません。


では続いて、入力フォームのあるページと動作を記述してみます。
これはnewアクションと言います。
下記の絵と、コードを参照して動きを確認しましょう。

このnewアクションは、
localhost:3000/posts/new
にアクセスするか、

もしくはViewfileの中で
<%= link_to 'new',new_post_path %>
で作られるリンクをクリックすると、
ブラウザにフォームが書かれたnewのページが表示されます。


![new_create.png](https://qiita-image-store.s3.amazonaws.com/0/316335/35acf8fc-c91a-b561-1b3c-6db01608aed5.png)

``` app/controllers/posts_controller.rb
def new
	@post = Post.new
end
```

```app/views/posts/new.html.erb
<%= form_for(@post) do |f| %>
  <div class="field">
		<%= f.label :件名 %>
		<%= f.text_field :title %>
	</div>
	<br>
  <div class="field">
		<%= f.label :本文 %>
		<%= f.text_area :body %>
	</div>
	<br>
	<%= f.submit :投稿 %>
<% end %>
```

@post = Post.newで@postという作業員さんに、Post.newという箱を預けます。
これが届くことで入力フォームに入力可能になり、
データベースに保存ができるようになります。
そして入力フォームを画面に表示するために、
fomr_forの記述がしてある場所に@postさんに来てもらい、
Post.newの内容の記述ができるようにブラウザで表示、
ページにアクセスしている人に記述をお願いし、
最後に送信ボタンを押してもらうと、createアクションに送信します。

ここが重要で、
Post.newでPostモデル用の箱を作ったので、
app/controllers/posts_controller.rb
の中にあるcreateに、その荷物を送るという手順になっています。
Post.newで新しく箱を準備するので「新規の投稿」、
新しくデータとデータをしまう場所をcreateしてもらう、ということです。

ちなみにposts_controller.rbは、
「Postモデルの」という意味のあるコントローラ名です。
複数形にするのがポイントです。（Railsの命名規則です）
ここではPostモデルと契約していることになっている、
と考えるとイメージしやすいと思います。
こうすることで、Postモデルのデータを取り扱う役割が持てます。

createアクションでは、以下のような記述と、作業内容になります。
今回は、データベースにしまう動きですので、ブラウザには表示しません。
コントローラしか記述をしないで大丈夫です。
こちらも画像を確認しながら、動きをチェックしてください。

このcreateアクションはnewに書かれたフォームで、
データを入力、送信ボタンを押すと動きます。

![create.png](https://qiita-image-store.s3.amazonaws.com/0/316335/e2a3a65f-eb15-de8c-4d6a-91ec1a0a7aa4.png)


``` app/controllers/posts_controller.rb
def create
  @post = Post.new(post_params)
  @post.save
  redirect_to posts_path
end
# private以下は、一番下のほうに記入します。ここから
private

def post_params
  params.require(:post).permit(:title, :body)
end
# ここまで。この下にendがひとつだけあるのを確認して下さい。
end
```
まず、
@postさんという作業員さんに、新たにPostモデルの箱を渡します。
しかし、渡す前に、post_paramsさんという別の作業員さんにチェックを依頼します。
newのフォームからもらったほうのPost.newの箱のデータを、
「Postモデルかどうか」→params.require(:post)
「カラムはtitleとbodyだけ受け付ける」→.permit(:title, :body)
という順番で検査します。
newのフォームからもらったPost.newのデータが正しければ、
createで作られたPost.newモデルにしまい直すという作業をします。
そしてしまい直したら、
@post.saveで@postさんは、倉庫にデータを収めに行ってくれます。
これらの作業は、Rails内部で行われているので、見えません。
しかし、このままですと、このページにアクセスしている人は、
データが登録できたかどうかが確認できません。
ですので、redirect_to posts_pathで、
ブラウザの表示をindexアクションのページに移動させるようにする必要があります。

ここまでで、createの仕事が終わりになります。


ではせっかくなので、続いてindexアクションについての記述を行いましょう。
indexアクションは、すべての投稿をまとめて表示する、という内容です。
今回は投稿後は必ずこのページに移動するように設定しています。

indexアクションは、
このnewアクションは、
localhost:3000/posts/
にアクセスするか、

もしくはViewfileの中で
<%= link_to 'new',posts_path %>
で作られるリンクをクリックすると、
Postモデルに保存されたデータの一覧ページにつながります。


![index.png](https://qiita-image-store.s3.amazonaws.com/0/316335/dcdf65d8-7955-3672-9d31-715387e2ee8a.png)

![index2.png](https://qiita-image-store.s3.amazonaws.com/0/316335/81425f99-1e53-ae60-bfcf-812a7c332bbc.png)

``` app/controllers/posts_controller.rb
  def index
  	@posts = Post.all
  end
```

これだけです。
これはどういうことをしているのかというと、
PostはPostモデルにアクセスします、という意味で、
.allはPostモデルに保存されたものをすべて持ってきてください、という意味です。

今回は@postsというトラックに、
Postモデルに保存されたものをすべてしまいました。
そして、しまい込んだあと、
Viewファイルに記述された@postsにデータが届くようになっています。
このデータをすべて同じレイアウトで並べられるように、
each文で、レイアウトを決め、すべてのデータを同じ展開の仕方で表示します。

Viewファイルに以下の表記をして下さい。

``` app/views/posts/index.html.erb

<h2>投稿一覧</h2>
<h3>件名/本文</h3>
<% @posts.each do |post| %>
	<%= post.title %>/<%= post.body %>
	<br>
<% end %>

```

そうすると、すべてのPostモデルのデータを、
```<%= post.title %>/<%= post.body %><br>
```
というレイアウトで繰り返して表示します。
棚にきれいに整列させて並べるような感じです。

では最後にshowアクションの記述を行ってみましょう。
showアクションは、
Postモデルに保存されたデータの中から、
保存されるごとに自動で番号が振られるidを基準に、
ひとつのデータを持ってくるように指定するアクションです。

このnewアクションは、
localhost:3000/posts/id（=保存された番号）
にアクセスするか、

もしくはViewfileの中で、
※この例はindex.htmlの@posts.eachの中で使われる想定です。
<%= link_to 'new',post_path(post) %>
で作られるリンクをクリックすると、
ブラウザにshowのページが表示されます。

今回は、
localhost:3000/posts/2
だった場合の動きです。
ちなみに、この場合二件以上データが投稿されていない場合は、
表示ができません。無いものは表示できないからです。

![show.png](https://qiita-image-store.s3.amazonaws.com/0/316335/3b8b1254-4361-7846-8619-662d8d28701d.png)





```app/controllers/posts_controller.rb
	def show
		@post = Post.find(params[:id])
	end
```

@が先頭についた変数をインスタンス変数、と言います。

Post.findは、Postのように先頭の文字を大文字に変更すると、
コントローラはPostモデルにアクセスする、という意味になります。
そして.findで「idを頼りに一件だけデータを選択します」という意味になります。
(params[:id])で、そのデータがidです、と確定します。


```app/views/posts/show.html.erb
<%= @post.title %>
<%= @post.body %>
```

などと書けば、データベースに保存されたPostモデルのカラムがそれぞれ表示されます。
ここまででデータベースへの保存と、
ページの表示に関する機能の実装方法を説明しました。




## Railsで最低限抑えるべきこと
最後に復習とまとめとして、
Railsで最低限抑えるべきことを記載します。

- Railsアプリを作るということは、
フォームに文字などを入れると、データベースに保存され、
自動で更新されるホームページを作るということ

- MVCはあくまでデータの出し入れと、
ホームページとしてデータをどう表示するかを制御しているというのが基本

- routesで各機能へのURL、pathの制御を行っている

- コントローラ内でPostとつけた場合、データベースから
Postモデル関係のデータを引き出す操作を行うこと。
@を付けた変数をコントローラで準備しないと、
Viewにはデータが届けられないこと
（回避する方法自体はある）

- Post.newという記述がデータベースへの保存には必要なこと。
  保存されたPostモデルデータは主にposts_controllerで取り扱うこと。
（回避する方法自体はある）

この点をひとまずしっかり抑えられれば、
初心者がRailsアプリケーションを作る上では十分です。
データの流れ、Railsの動きがしっかり分かれば、
悩みも半減すると思います。

少し長い記事になってしまいましたが、
ご覧いただきありがとうございました！

画像素材：かわいいフリー素材集いらすとや　様　(https://www.irasutoya.com/)