この一連のエントリは
Ruby on Rails 3 Tutorial: Learn Rails by Example (Addison-Wesley Professional Ruby Series)
で参考に学んだことを凝縮してお送りしています。
Ruby on Rails 3 Tutorial: Learn Rails by Example (Addison-Wesley Professional Ruby Series)
で参考に学んだことを凝縮してお送りしています。
describe "PUT 'update'" do目新しい部分としてはユーザー情報が更新されたことを確認するさいに「@user.reload」としてDBから読み直しています。読み直した値をつかって設定した内容と等しいことを確認しています。
before(:each) do
@user = Factory(:user)
controller.sign_in(@user)
end
describe "更新に失敗するケースの検証" do
before(:each) do
@attr = { :name => "", :password => "", :password_confirmation => ""}
end
it "設定変更ページを再表示すること" do
put :update, :id => @user, :user=> @attr
response.should reder_template('edit')
end
it "設定変更ページのタイトルであること" do
put :update, :id => @user, :user => @attr
response.should have_selector("title", :content => "設定変更")
end
end #更新に失敗するケースの検証
describe"更新に成功するケース" do
before(:each) do
@attr = { :name => "Saburou", :password => "barbaz",
:password_confirmation => "barbaz"}
end
it "ユーザー情報が更新されていること" do
put :update, :id => @user, :user => @attr
@user.reload
@user.name.should == @attr[:name]
end
it "ユーザー個人ページへ遷移すること" do
put :update, :id => @user, :user => @attr
response.should redirect_to(user_path(@user))
end
end #更新に成功するケースの検証
end #PUT 'update'
ではアクションを実装します。
def updateedit.html.erbの入力フィールドは「user[name]」といった名前がつけられいて、コントローラに渡ってくると「params[:user]」として渡されます。入力された名前にアクセスするには「params[:user][:name]」とします。
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
flash[:success] = "ユーザー情報を更新しました"
redirect_to @user
else
@title = "設定変更"
render 'edit'
end
end
ここでは「params[:user]」として入力されたフィールドを全てupdate_attributesに渡しています。
update_attributesでは渡されたパラメータをまとめてDBを更新します。
ここで悪意あるユーザーが不正なパラメータ(例えば admin=trueなど)を指定してもUserモデルでattr_accessibleを指定しているパラメータ以外は更新されません(第4回にやりましたね)。
さて、これでテストはパスします。
が、例えば適当なユーザーでサインインして「http://localhost:3000/users/1/edit」などとサインインユーザー以外のユーザーIDの編集ページを直接指定すると編集画面に遷移できてしまいます。
このままでは自分以外のユーザーに勝手に情報を変更されてしまいます。
自分の編集ページ以外にはアクセスできないようにしましょう。
テストコードは以下の通りです。
describe "自分以外のユーザー情報を更新できないこと" doまず今現在のユーザーとアクセス先のユーザーが一致するかどうかをチェックするヘルパmソッドを定義します。app/helpers/sessions_helper.rbに下記のメソッドを追加します。
before(:each) do
@user = Factory(:user)
@wrong_user = Factory(:user, :name => "Jirou")
controller.sign_in(@wrong_user)
end
it "自分以外のユーザー編集ページにアクセスしたらルートに飛ばす" do
get :edit, :id => @user
response.should redirect_to(root_path)
end
it "自分以外のユーザー情報更新が要求されたらルートに飛ばす" do
put :update, :id => @user, :user => {}
response.should redirect_to(root_path)
end
end #自分以外のユーザー情報を更新できないこと
def current_user?(user)current_userはcookieからユーザーを取得するメソッドです。渡されたユーザーとcookieを元にDBから取得したユーザーを比較した結果を返します。
user == current_user
end
次にこのヘルパの呼び出し処理を追加します。app/controllers/users_controller.rbに以下のプライベートメソッドを追加します。
def correct_userそして以下のフィルタを定義してedit、updateアクションの実行前にユーザーが一致するかをチェックするようにします。
@user = User.find(params[:id])
redirect_to(root_path) unless current_user?(@user)
end
before_filter :correct_user, :only => [:edit, :update]これでユーザー情報のアップデートはできあがり。
0 件のコメント:
コメントを投稿