Railsのフォーム画面とコントローラーについて備忘録

普通…と言い切って良いものか、Railsを学び始めた時は複数のコントローラーを使い分けることを意識していないと思う。というか、コントローラーが複数になるとどうなるのかと学習する前に挫折しているのかもしれないな。というのも、Railsでコントローラーを生成する際に、同時にいくつかのアクションも作ってしまうことが多いはず。app/views の下を覗くと、コントローラーの数だけフォルダが存在し、その中に生成したアクションに対応するビューが作られている。例えば、index.html.erbとか、show.html.erbとか。つまりコントローラーの数だけフォルダーとビューも作り分けられていて、Webの感覚だとhtdocsの下にいくつかディレクトリが切られ、そのなかで適宜htmlファイルが格納されている感じだ。

で、Railsの解説本は、最初はコントローラー1つで説明をする(もちろん読者を混乱させないようにするためなのだろうが)から、何でもかんでも1つのコントローラーに処理を書き込もうとして混乱し、挫折するんじゃないかという気がしてた。

僕もそんな感じで行き詰まっていたので、コントローラーを二つ作ってデータのやりとりしてみた。

適当な名前でプロジェクトを作り、コントローラーを2つ作る。

$ rails generate controller home index show
$ rails generate controller user show

homeにindexとshowが存在するのは、最初にhomeコントローラー内で完結する環境で実験を行ったため。本命は、home/index → user/show のコントローラー遷移とデータ表示だ。

1. config/routes.rb の設定

===ここから===
Rails.application.routes.draw do
  get 'user/show'
  post 'user/show'

  get 'home/index'

  post 'home/show'
  get 'home/show'

  # You can have the root of your site routed with "root"
  root 'home#index'
end
===ここまで===

home/show環境でも実験したため、設定中に  post 'home/show’ と get 'home/show' が残っているが、もちろん必要ない。

2. app/controllers 内の home_controller.rb と user_controller.rb の編集

home_controller.rbは次のように編集する。

===ここから===
class HomeController < ApplicationController
  def index
  end

  def show
   @msg=params[:contents]
  end
end
===ここまで===

user_controller.rbは次のように編集する。

===ここから===
class UserController < ApplicationController
  def show
   @msg=params[:contents]
  end
end
===ここまで===

home、userコントローラーでshowアクションが同じなので、ビューの設定でどちらのコントローラーでも実験が可能。

3. viewの編集 その1

app/views/home/index.html.erb を次のように編集する。

===ここから===

 <h1>Home#index</h1>
 <p>Find me in app/views/home/index.html.erb</p>

 <%= form_tag(:controller =>"user", :action => "show") do%>
   <div class="field">
     <%= label_tag 'text' %> <br />
     <%= text_area_tag 'contents','', :size => "60x10" %>
   </div>
   <div class="actions">
     <%= submit_tag "send" %>
   </div>
 <% end %>

===ここまで===

form_tag(:controller =>"user", :action => "show") はsubmitボタンをクリックされたあと、コントローラーuserのshowアクションへ遷移しろという指定。:controller =>"user", のコントローラー指定がない場合は、コントローラーhome内のshowアクションへ遷移する。

また、入力フォームエリアが小さいと使いづらいので、サイズ変更をしている。
text_area_tag 'contents','', :size => "60x10"

リファレンスによると、text_area_tag(要素名 [, エリア配下のテキスト, オプション]) で、サイズ指定はオプション扱いなので「エリア配下のテキスト」が存在しない場合は必ず ,’’, を記述しておくこと。そうでないと、例えば , :size => "60x10" が初期値として書き込まれたフォームが表示される。

4. viewの編集 その2

app/views/user/show.html.erb を次のように編集する。

===ここから===

 <h1>User#show</h1>
 <p>Find me in app/views/user/show.html.erb</p>
 <br />
 <%= sanitize(simple_format(@msg)) %>

===ここまで===

app/views/home/index.html.erbで入力されたテキストは、こんな感じで app/controllers/user_controller.rb に引き渡されてくる。

Parameters: {"utf8"=>"✓", "authenticity_token"=>”なにやらお呪いなテキスト", "contents"=>"秋深し。\r\n隣りはなにをする人ぞ。\r\n>>javasvript\r\n<javascript>", "commit"=>"send"}

実際どうなるかはあとで説明するが、<html>などのタグを直接書き込めるようにしているとセキュリティホールになり得るので、危険性を取り除くためにサニタイズして表示させている。viewファイルの中で、<%= sanitize(simple_format(@msg)) %> と記述することでタグを除去している。

simple_formatは入力された文章をそのまま表示させるために必要。単純に<%= sanitize(@msg) %> とした場合、改行コードが働かずに表示される。

で、実際、こんな感じで動作する。



0 件のコメント:

コメントを投稿