ControllerとView、Routeとのデータ交換

2020-10-02 hit count image

Ruby on RailsでControllerとView、そしてRouteを通じてデータを送る方法について調べてみましょう。

概要

Ruby on RailsでControllerとView、そしてRoute間でデータを送る方法についてデータを送る方法について調べてみます。

このブログポストはシリーズで作成されてます。詳しく内容は下記のリンクを参考してください。

ここで使ったソースコードはGithubで確認できます。

変数

データのやりとり方法を調べる前に、Rubyの変数について少し確認します。Rubyには下記のような変数たちを使えます。

名前特徴変数の使い方
ローカル変数- 特定なエアリア(アクション)中のみで使える変数
特定なエアリア(アクション)中だけ使える変数なので、特定なエアリア(アクション)中でしか参照できない。
var = 1
インスタンス変数- 1つのオブジェクト中のみで使える変数
- 変数が参照できるところはselfが指定するオブジェクトの内部に制限する。
@var = 1
クラス変数- 該当するクラスの全てのオブジェクトが共有する変数
- クラスメソッドを使ってアクセス可能
- クラスの内部メソッドを定義する前のClassの宣言すぐ下に宣言する。
@@var = 1
グローバル変数- プログラムのどこでも使える変数$var = 1

ControllerからViewへデータ伝達

上でまず変数をみた理由は、ControllerからViewへデータを伝達する時、インストアんつ変数を使うのでです。データが伝達することを確認するため、app/controllers/home_controller.rbファイルを開いて下記のように修正します。

class HomeController < ApplicationController
    def index
        @name = 'dev-yakuza'
    end
end

そして修正したアクションに該当するViewファイルを修正します。app/views/home/index.erbファイルを開いて下記のように修正します。

Hello <%= @name %>!!

確認するため、下記のコマンドを使ってRailsサーバを起動します。

bundle exec rails s
# bundle exec rails server

そしてブラウザでhttp://127.0.0.1:3000/に接続したら、下記のように設定した変数が画面に表示されたことが確認できます。

Ruby on Rails サーバー実行の結果 - ControllerとViewのデーター交換

このようにControllerからViewへデータを伝達するためにはインスタンス変数を使えます。

ViewからControllerでデータを伝達

ControllerからViewへデータを伝達するためには簡単にインスタンスヘンスを使えば良いでした。この理由はURLでRailsのウェブにリクエストが入ってくるとControllerがそのリクエストを処理して、Viewど表示するためです。

ViewからControllerへデータを伝達する意味は、ユーザがViewを使ってデータを入力したことです。

Viewは既にユーザのブラウザへ表示され他ので、ViewからControllerへデータを伝達する場合はユーザがデータを入力した時しかないのでです。

ViewからControllerへデータを送るためには、ウェブサービスでユーザの入力を送る方法と同じなので、GET方式とPOST方式でURLへリクエスト(Request)を送ることで送ることができます。

GET方式

GET方式でデータを送るため、Viewファイルを修正してみましょう。app/views/home/index.erbファイルを開いて、下記のように修正します。

Hello <%= @name %>!!<br/>
<a href="/?name=yakuza">Display yakuza</a>

そして送信されたGETパラメータを表示するためControllerを修正します。app/controllers/home_controller.rbファイルを開いて下記のように修正します。

class HomeController < ApplicationController
    def index
        name = params[:name]
        @name = name ? name : 'dev-yakuza'
    end
end

GET方式なのでデータを送るのでaタグを使ってデータ(name=yakuza)を送りました。このように送信されたデータはControllerでparamsと言うヘンスを使ってデータを取得することができます。(params[:name])

POST方式

POST方式でデータを送るため、Viewファイルを修正してみましょう。app/views/home/index.erbファイルを開いて下記のように修正します。

Hello <%= @name %>!!<br/>
<a href="/?name=yakuza">Display yakuza</a><br/>
<form action="/" method="POST">
  <label for="name">name:</label>
  <input type="text" name="name" />
  <input type="submit" />
</form>

そしてブラウザをみると下記のような画面が確認できます。

POST転送 - データを入力する前の画面

そして入力欄へデータを入力してSubmitボタンを押したら下記のようなエラーが発生します。

POST転送 - データ送信エラー画面

エラーメッセージ(Routing Error)を見ると分かると思いますが、Route設定をしてないので、このようなエラーが発生しました。

まず、今現在のRouteファイルを確認するため、config/routes.rbファイルを開いてみます。

Rails.application.routes.draw do
  get '/', to: 'home#index'
end

上のファイル内容でも分かると思いますが、Railsは/のURLでget方式のリクエストだけ連結されてます。したがって、POST方式のリクエストがくると、上のようにRouting Errorが発生します。

そしたら、POSTのリクエストを受けるように、Routeを修正してみます。config/routes.rbファイルを開いて下記のように修正します。

Rails.application.routes.draw do
  get '/', to: 'home#index'
  post '/', to: 'home#index'
end

そして、また、submitボタンを押すと下記のようなエラーメッセージが表示されることが見えます。

POST転送 - データ転送エラー画面 authenticity token

他の言語のフレームワークようにRailsも基本的セキュリティーの脆弱性を保護してます。ここでRailsはCSRF - Cross-site request forgeryの脆弱性を保護するため、POSTデータを送信する時、特定キー(key)を一緒に送るようにしてます。

このエラーを解決するためにはPOSTデータを転送する時、authenticity_tokenと言うパラメータでRailsが提供するform_authenticity_tokenを一緒に送る必要があります。

もう一回app/views/home/index.erbファイルを開いて下記のように修正します。

Hello <%= @name %>!!<br/>
<a href="/?name=yakuza">Display yakuza</a><br/>
<form action="/" method="POST">
  <input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
  <label for="name">name:</label>
  <input type="text" name="name" />
  <input type="submit" />
</form>

そしてまた、http://127.0.0.1:3000/接続して、入力欄にtestを入力してsubmitボタンを押すと下記のようにデータが上手く送信されて表示されることが確認できます。

POST転送 - データ転送成功画面

完了

これでControllerとViewの間でデータを転送する方法についてみてみました。

ControllerからViewへデータを転送するためにはインスタンス変数を使って、ViewからControllerへデータを送信するためにはGET/POST形式でデータを転送しました。 POST方式で転送するため、RouteへPOSTのURLも追加してみました。

本格的データを使う前、準備段階でControllerとView間へデータを転送する方法をみてみました。次のブログポストではデータをDBへ保存して、保存したデータを表示する方法についてみてみます。

参考

このブログポストはシリーズで作成されてます。詳しく内容は下記のリンクを参考してください。

ここで使ったソースコードはGithubで確認できます。

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

Posts