2011年9月6日火曜日

Rails3を初歩から学ぶ#16 サインアウト

この一連のエントリは
Ruby on Rails 3 Tutorial: Learn Rails by Example (Addison-Wesley Professional Ruby Series)
で参考に学んだことを凝縮してお送りしています。

前回まででサインインに関する処理が一通り完成したので、今度はサインアウトを実装しましょう。
spec/controller/sessions_controller_spec.rb に以下の検証コードを追加します。

describe "DELETE 'destroy'" do
it "未認証状態になり入り口に戻る" do
user = Factory(:user)
controller.sign_in(user)

delete :destroy
controller.should_not be_signed_in
response.should redirect_to(root_path)
end
end #DELETE 'destroy'
もう目新しいことはありません。
次にsign_inに対応するsign_outをヘルパメソッドとして定義しましょう。
app/helpers/sessions_helper.rbに追加します。

def sign_out
cookies.delete(:remember_token)
end

これだけです。次にdeleteアクションを実装しましょう。
sessions_controller.rbを編集します。
ちなみにusers_controller.rbじゃないです。意味的にこちらのdeleteはユーザーを削除することになるので、実装はいつかそのうちに。

def destroy
sign_out
redirect_to root_path
end
destroyアクションは以前sessions_controller.rbを生成した際に既に空で定義されているハズです。なのでそこに先ほど定義したサインアウトメソッドとリダイレクトの呼び出しを追加するのみです。
アプリケーションの入り口を示す意味で「root_path」を指定していますが、これはまだ未定義なのでconfig/route.rbに定義します。

resources :users
resources :sessions, :only => [:new, :create, :destroy]
match '/sessions/delete', :to => 'sessions#destroy' root :to => 'sessions#new'
赤字の箇所が追加分です。
ここではルートとしてサインインページを指定しています。
この状態で「http://localhost:3000/」とするとサインインページに行って欲しいんですが、public/index.htmlというファイルが存在すると、これが強制的に表示されます。
なのでrmコマンドで削除しておきましょう。
後はどこかにサインアウト用のリンクを追加すれば完成です。
これを期に各ページ共通のヘッダ部分を定義しましょう。
部分テンプレートとして定義します。
app/views/layouts/_header.html.erb を作成して以下のように編集します。
<header>
<nav class="round">
<ul>
<% if signed_in? %>
<li><%= link_to "ユーザー一覧", users_path %></li>
<li><%= link_to "プロフィール", current_user %></li>
<li><%= link_to "設定変更", edit_user_path(current_user) %></li>
<li><%= link_to "サインアウト", sessions_delete_path, :method => :delete %></li>
<% else %>
<li><%= link_to "サインイン", new_session_path %></li>
<% end %>
</ul>
</nav>
</header>
まとめてリンクを設定しました。設定変更のedit_user_pathだけは現時点で該当するアクションを実装していませんが、ついでに定義してしまいました。
こちらは次回作成しましょう。
それでは app/views/layouts/application.html.erb に今作成した部分テンプレートの呼び出しを追加します。

<div class="container">
<%= render 'layouts/header' %>
<section class="round">
<% flash.each do |key, value| %>
<%= content_tag(:div, value, :class => "flash #{key}") %>
<% end %>
</section>
<%= yield %>
</div>
renderメソッドでlayouts/headerを指定しています。これで部分テンプレート「_header.html.erb」が呼ばれます。その他、見た目用に少し手を入れています。CSS未設定なので見た目もへったくれも無いですが。


ここまで出来たらテストを実行してNGが0件であることを確認して、ブラウザで動作を見てみましょう。

ではテストを実行して全てパスすることを確認したら実際に動かして確認してみましょう。

0 件のコメント:

コメントを投稿