Blank?=False

「呉下の阿蒙にあらず」をモットーにしたITエンジニアの日々

基礎RubyOnRails Chapter3-1 コントローラとアクション

f:id:stonebeach-dakar:20160530220309p:plain

今回は、コントローラとアクションについて学習してきます。

改訂3版基礎 Ruby on Rails (KS IMPRESS KISO SERIES)

改訂3版基礎 Ruby on Rails (KS IMPRESS KISO SERIES)

コントローラとは?

Railsのコントローラは、モデルからデータを受け取って、ビューをレンダリングする、というのが基本的な役割で、つまりモデルとビューの中継ぎ的な機能。
前々回紹介したMVCモデルを見ても、モデルとビューはコントローラを介して繋がっている。
f:id:stonebeach-dakar:20160607062358p:plain
個人的に、MVCモデルの中で一番説明が難しい機能で、見た目となるビュー,データそのものとなるモデル と違い、はっきりした動きが決まっていないのもコントローラの特徴のような気がする。
なので、コントローラ何でも詰め込む、なんて実装になってしまうという話もよく聞く。

コントローラクラスは、ApplicationControllerというクラスを継承して作成する。

class SampleController < ApplicationController
end


アクションとは?

コントローラクラスのパブリックメソッドをアクションと言い、Webページの1つのページ、機能を実現するもので、例えばshowというアクションはデータを表示する機能をもったページ、という感じ。

アクションが行うことは、データを表示するものであれば、モデルからデータを取得し、対応するビューに渡す、という役割となる。
特にデータを表示しないアクション(aboutページなど)は、特に機能がなく、メソッドを宣言するだけということもある。

アクションに対応するVIEW

1つのアクションに対し、1つ(複数組み合わせる場合もあり)のビューとなるerbテンプレートが必要となる。
erbテンプレートとアクションは、Rails命名規則によってリンクされるため、必ずアクション名とテンプレートファイル名をあわせる必要がある。

アクション以外は全部プライベート!

パブリックメソッド=アクションとなるので、アクション以外のメソッド(前処理、後処理等)はすべてPrivateなメソッドにする必要がある。
本書では、

意図しないコードが実行される可能性がある

と書かれている。コントローラのアクション以外のメソッドにリダイレクトされたりした場合、対応するerbテンプレートがないのでnot foundになりますよね。

アクション例

よく見るアクションメソッドは、以下のようなものがある。(と言うより、CRUDの基本的なパターン)

  • Index データの一覧を表示するアクション
  • show データの詳細を表示するアクション
  • edit データを編集するアクション
  • destroy データを削除するアクション
  • new データを新規作成するアクション


コントローラとモデルの命名規則

Rails設定より規約を設計哲学としているため、様々なものにルールが設けられており、そのルールに従う(レールに乗る)ことで高い生産性を持っている。
この命名規則はそのルールの1つで、以下の様なルールとなっている。
なお、Memberというモデルを例としている。


コントローラの命名規則

項目 ルール 備考
コントローラクラス名 ◯◯Controller MembersController 先頭はRubyのルール通り、英大文字。モデルの複数形
コントローラクラスファイル名 ◯◯_controller.rb members_controller.rb モデルの複数形
erbテンプレートフォルダ名 app/views/◯◯ app/views/members モデルの複数形

モデルの命名規則

項目 ルール 備考
データベースのテーブル名 ◯◯ members 複数形、先頭は小文字
モデルクラス名 ◯◯ Member 単数形、先頭は英大文字
モデルクラスファイル名 ◯◯.rb member.rb 単数形


モデルは単数形、複数のモデルを持つコントローラ、テーブルは複数形という感覚で覚えるといいのかな。

コントローラが受け取るパラメータ

コントローラクラスは、params[key]というメソッドでコントローラに渡されたパラメータを取得することができる。このパラメータは、HashクラスではなくActionController::Parametersというクラスのオブジェクトで、シンボルで文字列でも値を取り出せるようになっている。
例えば、params[:id]とした場合、下のようなURLの

http://example.com/user/show/1 http://example.com/user/show?id=1

1の部分を取得できる。キー値はroutes.rbで指定したものになる。(rake routesでルートの一覧を表示した時に表示される:idなどがキー値)
コレをどう使うかというと、例えばshowアクションでparamsから取得したidを使って、ユーザーのデータをモデルから取得してビューに渡す・・・という処理が作れる。

class SampleController < ApplicationController
  def show
     @user = User.find(params[:id])  #=>id値のユーザーをインスタンス変数に格納してビューに渡す
  end
end

また、params[:controller]でコントローラ名、params[:action]でアクション名も取得することができる。

class SampleController < ApplicationController
 def foo
   render text: "#{params[:controller]}##{params[:action]}" #=> SampleController#foo
 end
end


リダイレクトの実装

リダイレクトとは、前回紹介したとおりURLをレスポンスとして渡して、そのURLに移動させるというもの。
実装はそのまんまredirect_toというメソッドをコールする。
以下の例では、fooというアクションが呼ばれるとbarというアクションに移動させるというもの。

def foo
 redirect_to action: bar
end

def bar
 render text "bar"
end 


redirect_toで移動する先のURLの渡し方は様々で、

  • fooコントローラのbarアクションを指定
redirect_to controller:foo, action:bar
  • URLを指定
redirect_to "http://www.example.com"
  • ルーティング設定で作成された_pathヘルパー
redirect_to foo_path

等がある。詳細はリファレンスをガリガリ読みましょう。

redirect_to - リファレンス - - Railsドキュメント

フラッシュの実装

フラッシュとは、アクションとアクションの間で情報を受け渡す機能で、この機能を使って何らかのアクションを行った後リダイレクトを行い、アクションの結果を表示する、ということができる。
たとえば、ログインページでログインに成功した後、indexページにリダイレクトし、"ログインに成功しました"というメッセージを表示する、という機能が実現できる。

以下の例は、fooアクションがbarアクションにリダイレクトし、barアクションがflashメッセージを表示する、もの。

def foo
   flash[:notice] = "リダイレクトしたよ"
   redirect_to action: bar
end

def bar
  render text: flash[:notice]
end


このフラッシュは1度読み込んだ後そのデータがnilになる、という性質が有り、一度しか読み込めないものとなっている。
そのため、一度フラッシュメッセージが表示された後にページの再読み込みを行うと、フラッシュメッセージは表示されなくなる。
上記の例では、barを再読み込みした場合、何もメッセージが表示されなくなる。

フラッシュは基本的にflash[:key]という形でデータの入出力を行うが、成功メッセージとなるnotice,エラーメッセージとなるalertはそれぞれflash.notice="メッセージ", flash.alert="メッセージ"という形での入出力が可能となっている。

また、リダイレクトでフラッシュがよく使われるため、redirect_toのオプションとしてフラッシュを設定することも可能となっている。(ただし、自分の環境だと何故かできない。Railsのバージョン?)

[Rails]ControllerからViewへ簡易メッセージ表示するflashオブジェクトについて | Coffee Breakにプログラミング備忘録