最初から考える方法は次のとおりです。
1) アプリが行う唯一のことは、HTTP REQUESTS への応答です。
最も一般的なリクエストの種類は次のとおりです。
他の種類の HTTP リクエストもあり、最も重要なのは PUT、PATCH、および DELETE です。Rails は REST パターンに従います。つまり、これらの HTTP 動詞に特定の意味を割り当てます。
2) リクエストがアプリに入ってきたら、コントローラ アクションにルーティングする必要があります。
このファイルは、Rails ルーター ( ActionDispatch routes.rb
) に対する一連の指示であり、ルーターにリクエストの送信先を指示します。次のように、「標準」の rails リソースがショートカットとして提供されます。
resources :things
これは次のことを意味します。
GET /things => things#index
GET /things/:id => things#show
GET /things/new => things#new
GET /things/edit/:id => things#edit
POST /things => things#create
PUT /things/:id => things#update
DELETE /things/:id => things#destroy
これらは標準の RESTful アクションと見なされますresources :things
。宣言によって設定されるものは他にありません。そのため、コントローラーに他の非標準アクションを実行させたい場合は、それらを手動で追加する必要があります。
特定のレコードに対してアクションを実行する場合は、次を使用するのが最善の方法です。
resources :things do
member do
get 'vote_up'
end
end
これは、誰かが GET リクエストを行うと、アクション/things/123/vote_up
をトリガーする必要があることをルーターに伝えます。ThingsController
vote_up
これらはすべて、 Rails Guideで詳細に説明されています。すべてを読む必要があります。
3) コントローラーの仕事は、リクエストに対するレスポンスを送信することです。
通常、これは、データベースからレコードをロードし、そのレコードのビューをレンダリングするようなことを意味します。
各コントローラ アクションは、着信要求に応答を返すことで終了します。この応答は、render
呼び出し (何らかのデータを何らかの形式で送り返すことを意味します) またはredirect
呼び出し (基本的に新しい要求を作成し、別の要求の応答を取得する) のいずれかです。
Rails では、リダイレクトによってリクエストが別のコントローラー アクションに効果的に送信されます。
Render 呼び出しは、要求に対する応答としてデータを送信します。
を呼び出すとrender :new
、これは へのショートカットrender :template => :new
であり、(またはその他の) テンプレートをロードapp/views/things/new.html.erb
し、コントローラ (通常はインスタンス変数) からデータを送信し、テンプレート言語 (erb、haml など) を使用してこれを評価します。この結果は次のようになります。 HTML の大きな文字列で、コントローラーがブラウザーに配信します。
自分でこれを確認したいですか?render :text => 'Hello World'
、または次のようにコントローラーを終了してみてください。
render :inline => '<!DOCTYPE html><head><title>Inline Wow!</title></head><body>Mind blown.</body></html>'
何が起こるか見てください。
応答 (レンダリング) する場合、ページ全体の情報 (head、body など) を含む「通常の」HTML テンプレート、または Ajax で使用される部分テンプレートを送信できます。JSON や XML などの生データを送信することもできます。実際にはすべて単なるテキストであり、そのテキスト (およびそれに付随する HTTP ヘッダー) の内容に応じて、ブラウザー、スクリプト、またはクライアント アプリケーションがそれを適切に処理します。
繰り返しますが、Rails ガイドを参照してください。
4) リクエストがブラウザによって行われた場合、おそらく HTML を送り返したいでしょう。リクエストが Ajax によって行われた場合、おそらく JSON を送り返したいでしょう。
カスタム アクションの場合vote_up
、テンプレートをまったく表示せずにリダイレクトするだけです。したがって、次のようなものがあるかもしれません:
ThingsController < ApplicationController
def vote_up
@thing = Thing.find(params[:id])
@thing.vote_up
redirect_to @thing
end
end
さて、ルーターの利点の 1 つは、URL ヘルパーを提供することです。前に示したようにルートとアクションを作成した場合、「show thing」ページで次のような URL を作成できます。
link_to 'Vote up this thing!', vote_up_thing_path(@thing)
へのリンクが作成されthings/123/vote_up
、誰かがそれをクリックすると、 のvote_up
アクションでコードが実行ThingsController
され、ショー シング ビューにリダイレクトされます。
5) テンプレートは、リンクとフォームを使用してコントローラーにメッセージを送信します。リンクは GET リクエストを作成し、フォームは POST リクエストを作成します。
AJAX リクエストを開始したい場合は、それで問題ありません。その場合、Javascript でリクエストを作成し、レスポンスを処理するだけで済みます。したがって、たとえば、テンプレートに次のようなものを入れることができます。
= link_to 'Vote up this thing', vote_up_thing_path(@thing), :id => 'vote-up-button'
次に、Javascript (jQuery を使用) では、次のような関数を作成できます。
$(function(){
$('a#vote-up-button').click( function(event){
event.preventDefault();
$.ajax({
url: this.attr('href'),
type: 'GET',
success: function(){...},
error: function(){...}
});
});
});
この場合、jQuery Ajax メソッドは取得リクエストを作成し、取得したレスポンスに基づいてコールバック関数を実行しています。
6) コントローラー/ルートの構造は、作成できるリクエストの種類には影響しません。どのアクションがどの URL のどの HTTP メソッドに応答するかだけに影響します。
コントローラー アクション内で行うことは、javascript や html リクエストなどに応答する準備ができているかどうかを決定します。
Rails は確かに、ブロックを使用して 1 つのコントローラー アクションで複数の要求形式を処理できますがrespond_to
、実用性の問題として、ルートが 1 つまたは別の形式にのみ応答するように選択した場合、物事がはるかにスムーズに機能することがわかります。
IE: 通常のページ読み込みリクエスト (インデックス、表示、新規作成、編集) を HTML リクエストだけにしてから、追加したい追加の AJAX アクションを Javascript のみにします。HTML ではなく JSON で応答します。もちろん、これを行う必要はありませんが、そうすると生活が楽になります。
これにより、アプリで何が起こっているかをより明確に把握できることを願っています。Rails へようこそ。あなたは素晴らしいコミュニティに参加しています!