アプリケーションを動的にします


動的サーバーの応答


これで、リクエストをアクションに送信するルートが得られました。アクションをビューに表示しましたが、これまでのすべてのコンテンツは静的でした。


私たちのRailsアプリケーションは本質的に、HTML文書を取り出しHTTPレスポンスにラップしてクライアントに返すファイルサーバです。


これは初期のWebの主なパラダイムで、Webサーバーがリクエストに応答して静的なドキュメントを返送します。しかし、現代のウェブは、リクエストに応答するために即座に応答を集めることができるウェブの「アプリケーション」を生み出しました。


Webアプリケーションの動的な性質は、主に次の2つのソースから来ています:


1クライアントは、サーバーが応答するURL内にデータを埋め込みます。 たとえば、ブラウザ「https://www.google.com/search?q=robots」を入力すると、「ロボット」の検索結果のみを含むウェブページを動的に組み立てるよう、Googleに求めています。


2サーバーは、サーバーのデータベース内のデータの内部状態に基づいてデータに応答します。 たとえば、ブログを訪問すると、サーバーはデータベースに格納されているブログ投稿を取得し、このデータに基づいてWebページを動的に組み立てます。


この2つのシナリオを次のトピックで詳しく見ていきます。


動的ドキュメントと組み込みRuby


ERBは「組み込みRuby」の略です。 Rubyコードをテキスト文書に埋め込んで動的な文書を作成できるテンプレートエンジンです。


ERBテンプレートでは、識別するためにRubyコードを<%…%>タグの内側に配置する必要があります。 さらに、<%= ruby_expression%>構文を使用して、ルビコードの値をHTMLドキュメントに入れることができます。


テンプレートをHTMLドキュメントに「レンダリング」するときは、「レンダリングエンジン」(この場合はERBレンダリングエンジン)を使用してテンプレートを実行してから、埋め込まれたRubyコードを実行して出力します。


たとえば、このERBテンプレート


<html>
  <body>
    <% name = "John" %>
    <p>Hello, <%= name %>!</p>
  </body>
</html>


以下にレンダーします


<html>
  <body>
    <p>Hello, John!</p>
  </body>
</html>


この例では、ERBテンプレート内の変数名に値「John」を割り当ててから、HTML文書のレンダリングに使用しました。テンプレートは常に同じ結果にレンダリングされるので、これは面白くないです。


テンプレートを以下のように残すでけで


<html>
  <body>
    <p>Hello, <%= name %>!</p>
  </body>
</html>


テンプレートの外側から変数名前の値を渡します。変数名前の値が “John”の場合、このテンプレートは同じ結果にレンダリングされます。


クエリパラメータに応答します


これで、ERBテンプレートを使用して動的ドキュメントをレンダリングする方法がわかったので、リクエストURLに名前を渡して、 “Hello、John!”のようなカスタム挨拶に応答させます。


これを行うために、HTML文書の名前をhello_world.html.erbに変更します。 Railsでは、この規約は、最終的にHTML文書にレンダリングされるERBテンプレートであることを意味します。


ERBテンプレートはよく見かけがあります。


app/views/application/hello_world.html.erb
<html>
  <body>
    <p>Hello, <%= name %>!</p>
  </body>
</html>


クライアントからサーバーに値を渡す方法はいくつかありますが、最も基本的なのはURLのクエリパラメータ(http:// localhost:3000 / hello_world?name = Johnなど)を使用することです。パスの?後ろの部分name = Johnは、サーバーによって解釈されるクエリ文字列です。


アクションでこれらのパラメータにアクセスする方法を見てみましょう:


app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  def hello_world
    name = params['name']
    render 'application/hello_world', locals: { name: name }
  end
end


Railsはクエリパラメータをparamsというハッシュに解析します。 この処理では、名前クエリパラメータの値を取得し、ERBレンダリングエンジンに渡してhello_world.html.erbテンプレートをレンダリングします。


もし前のコード行が混乱しているように見える場合は、以下のように書くこともできます。


render('application/hello_world', { locals: { name: name } })


これは実際には2つの引数を持つメソッド呼び出しであり、2番目の引数はキー/値のペアを持つハッシュです。キーはlocalsで、値は別のハッシュです。ERBエンジンでハッシュの:localsキーが見つかると、そのキーの値を使用してテンプレートがレンダリングされます。


Now if you type into your browser http://localhost:3000/hello_world?name=John you will see "Hello, John!".


これはうまくいきますが、我々はまた少し問題を導入しました。つまり、/ hello_worldを単独で打つと、次のようになります:


Hello, !


その理由は、nameはここにはnilであります。 キーnameで渡されるクエリパラメータはありません。 これはテンプレートがレンダリングされるときに上記のメッセージが不鮮明になることがあります。


これをいくつかの方法で修正することができますが、アクション内で名前をデフォルト値に設定しましょう:


app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  def hello_world
    name = params['name'] || "World"
    render 'application/hello_world', locals: { name: name }
  end
end


これでクエリ文字列にnameを渡さなければ、hello, wolrd!をみることができます。
params [‘name’] || 上の ‘world’の行、|| (論理OR)は、何かがparams [‘name’]にあるかどうかを調べるためのチェックとして機能します。 その値がtruthy(falseまたはnil以外の値)の場合、単に値を返します。 それ以外の場合(「OR」)、「World」を返します。


URL取得パターンにレスポンス


クエリパラメータは、サーバーにデータを渡すのに便利ですが、それだけではありません。 ルーティングとデーターキャプチャのためのURLマッチングパターンを指定することもできます。


たとえば、routes.rbファイルに新しい行を追加します。


config/routes.rb
Rails.application.routes.draw do
  get '/hello_world/' => 'application#hello_world'
  get '/hello/:name'  => 'application#hello_world'
end


/ hello / Johnを訪問すると Hello、John!も表示されます。


パターン / hello /:nameは、/ hello / JohnのようなURLを持つリクエストをApplicationControllerのhello_worldアクションにルーティングするようにRailsに指示します。nameのプレースホルダーにマッチングする値、この場合、Johnはコントローラ内でparams [‘name’]を使用してアクセス可能になります。


上記の私たちのルートについて最後に気づくべきことは、同じアクションを指す2つのルートがあることです。これには何も問題はありません.Railsは単にURLパターンに一致する最初のルートを使用します。