ここまでの学習で、モデル、ビュー、コントローラーの役割を確認してきた。
次に、いよいよこれらを連携させて、データベースから情報を取得し、それをビューに表示させる方法を学んでいく。
- データベースからデータを取得する方法
- 取得したデータをビューに表示させる方法
処理の全体像
前回の投稿で、データベースにデータを格納した。
これから、そのデータを取り出してビューに表示できるようにする。
そのためには、モデル、ビュー、コントローラーを連携させる必要がある。
どのような方法で実現するのか、まずは処理の全体像を確認しておく。
大きく分けて3つのことを行う。
- データベースから必要なデータを取得する
- 変数(インスタンス変数)にデータを格納する。
- 変数の中身をビューで表示
なお、①②はコントローラーに、③はビューにメソッド等を記述する。
①データベースからデータを取得する
データの取得方法は、前回の復習となる。
findというメソッドが使うと、テーブルから1件だけデータを取得することができた。
Tweet.find(1)
この記述によって、tweetsテーブルからid1番のデータを取得することができる。
これは、言い換えるとコントローラーがモデルに対してデータを取ってくるように依頼するためのコードということになる。
②変数にデータを格納する
次に、コントローラーからビューに対して、今取ってきたデータを表示するよう依頼する必要がある。
そのために、データをインスタンス変数に格納してからビューに渡す必要がある。
荷物を一度箱に入れて、その箱を手渡すようなイメージです。では、このインスタンス変数とは何か確認しておく。
インスタンス変数とローカル変数
Rubyの変数にはいくつかの種類があるが、Railsでよく使うインスタンス変数とローカル変数について押さえておく。
どちらも変数のため、数値や文字を格納できるという機能に変わりはない。
ただ、その変数にアクセスできる範囲(スコープ)が異なる。
以下のように使い分けると覚えておく。
変数の種類 | 使い方 |
---|---|
インスタンス変数 | コントローラーで代入したデータをビューで使いたい場合 |
ローカル変数 | コントローラーのアクションで代入したデータを、そのアクション内で使いたい場合 |
また、インスタンス変数を使用する場合は、変数名の前に「@」の記号をつける。
実際に記述してみる。
app/controllers/tweets_controller.rb
class TweetsController < ApplicationController def index @tweet = Tweet.find(1) end end
3行目に追加した記述によって、データベースから取得したデータを「@tweet」というインスタンス変数に入れることができる。
次に、このデータをビューで表示できるようにする。
③ 変数の中身をビューで表示する
ビューでインスタンス変数の内容を表示されるためには、コントローラーからビューにデータを渡す処理が必要である。
しかし、実際にそのコードを書く必要はない。
インスタンス変数にデータを入れておきさえすれば、自動的にビューに渡される仕組みになっているためである。
記述として必要なのは、データを受け取ったビューが、それをどのように表示するかという指定になる。
ビューを編集する
app/views/tweets/index.html.erb
<%= @tweet.name %> <%= @tweet.text %> <%= @tweet.image %>
記述したら、仮想サーバーを起動して結果を見てみる。
ターミナル
$ pwd # pictweetフォルダにいることを確認し、違っていたら以下を実行します。 $ cd ~/environment/pictweet $ rails s
上記コマンドを実行したら、メニューの「Preview」->「Previwe Running Application」をクリックする。
下記のアイコンをクリックすると別ウィンドウでアプリを確認することができる。
別ウィンドウが開いたら、表示されているURLの末尾に「/tweets」を追加してエンターキーを押す。
このように、データベースに追加したname, text, imageカラムの内容が表示されれば成功である。
これでコントローラーがモデル、ビューと連携できたことになる。
続いて今ビューに書いたコードの意味を確認していく。 1行目を確認する。
「@tweet.name」という記述が、「<%= %>」に囲まれている。この2つを個別にみていく。
<%= %>の意味
Railsのビューでは、ERBテンプレートが用意されている。
これは、htmlにRubyの変数やメソッドを埋め込むことができるものである。
「<%= (変数名) %>」「<%= (メソッド) %>」 このように、変数名やメソッドを囲むように記述することで、その結果をビューで表示されることができる。
カラムの内容の取り出し方
次に、「@tweet.name」という書き方の意味を確認する。
これは、1つのレコードからカラムの中身を取り出している。
@tweetという変数は、Tweet.find(1)を実行した結果なので、tweetsテーブルのレコード1件分のデータが入っている。
つまり、id, name, text, image, create_at, updated_atカラムの情報が全て入っているわけである。
その中から、例えばnameカラムの値を取り出したいときは以下のように書く。
@tweet.name
この時の「.(ドット)」は「〜の」という意味だと捉えるとわかりやすい。「@tweet」の「name」は「こま」という感じである。
textやimageに関しても同様である。
複数のデータを表示させる
ここまでで、データベースの内容をビューに表示することができた。
しかし、できたのは表示させるデータがレコード1件分の時のみである。
複数のデータを一度に表示させる方法を学んでいきたい。
複数のデータを変数に代入する
先ほどはfindメソッドを使用して、idが1番のデータをインスタンス変数に代入した。
今回は「all」メソッドを使って、tweetsテーブルの全件を表示させる。
tweetsコントローラーを編集する
app/controllers/tweets_controller.rb
class TweetsController < ApplicationController def index @tweets = Tweet.all end end
findメソッドの代わりにallメソッドを使用して、テーブルのデータ全件を取得する。
また、「@tweet」となっていた変数を「@tweets」に変更していることに注意が必要である。
変数名は出来るだけわかりやすく命名することが重要である。
データが1つしか入らない場合は単数形を、複数入ることが想定される場合は複数形で名前をつける。
複数データを表示できるようにしよう
複数のデータを表示されるためには、ビューのメソッドも書き換える必要がある。
例えばテーブルに3件のデータが入っていた場合、表示も3回繰り返さなくてはいけないからである。
最初に実際の動きを確認してから、プログラムの書き方について学習する。
ビューを編集する
ビューファイルを以下の通り書き換える。
app/views/tweets/index.html.erb
<% @tweets.each do |tweet| %> <p><%= tweet.name %></p> <p><%= tweet.text %></p> <p><%= tweet.image %></p> <% end %>
書き換えができたらブラウザをリロードして結果を見てみる。
このように繰り返し表示がされた。
続いてコードの確認をしていく。
ここでのポイントは「eachメソッド」である。
これから何度も使う大事なメソッドのため、使い方や機能をきちんと押さえておく。
eachメソッド
eachメソッドは配列などからデータを順次取り出して、そのデータの個数分だけ処理を繰り返すためのメソッドである。
以下の順にメソッドは実行される。
- 配列の中からデータを1つ取り出す。
- 取り出したデータを変数に代入する
- その変数を利用して、処理1、処理2が実行される
- 全ての変数に対して処理が終わるまで繰り返す。
これをもとに、先ほど書き換えたコードを見てみる。
<% @tweets.each do |tweet| %> <p><%= tweet.name %></p> <p><%= tweet.text %></p> <p><%= tweet.image %></p> <% end %>
このような流れでプログラムが動くことになる。
1行目の<%の後に「=」がついていないことに注意が必要である。
書き方を間違えるとおかしな表示がされるので下記の違いを把握しておく。
<%= %>と<% %>の違い
<%= %>と<% %>は、いずれもビューの中でRubyの変数やメソッドを使えるようにするものである。
ただし、表示のされ方に違いがありますのでどちらを使うべきかその都度注意が必要。
種類 | 表示のされ方 |
---|---|
<%= %> | 変数の中身やメソッドの結果がビューに表示される |
<% %> | メソッドは実行されるが、結果はどこにも表示されない |
今回のコードの例では、eachメソッドは使いたいが、その結果を表示する必要はない(表示したいのはあくまでもtweet.nameなど)。
そのため<% %>でメソッドを囲っている。
なお、@tweetsという変数は配列ではありませんが、複数のデータが入っていて配列と同じように扱うことができる。そのためeachメソッドが使える。
また<p>タグを使用していますが、これはHTMLのタグで余白や改行を追加してみやすくするためのものである。
これで複数のデータであっても表示できるようになった。
次の章ではアプリのデザインを整えていく。