(Rails 3を使用)ユーザーとユーザーセッションを管理するためにauthlogicをセットアップしました(ユーザーコントローラーとuser_sessionsコントローラー、および関連するビュー、モデルなどを使用)。管理者とクライアントの 2 つのレベルのユーザーがいます。管理者はユーザーの作成とユーザーの編集を行うことができ、ユーザーは Web サイト上のドキュメントを閲覧することしかできません (ユーザーの編集権限や閲覧権限はまったくありません)。
次に、クライアントが Web サイトでパスワードを変更できるようにする別のコントローラー (reset_password) を実装しました。これを行うために、クライアントがクライアントを編集できるようにしました (クライアントが自分自身を編集できるようにするため)。ただし、クライアントがパスワードを変更できるフォームは、管理者がクライアントを作成できるフォームよりもはるかに制限されています。
私が抱えている問題は、クライアントがパスワード編集フォームに移動し、無効なパスワードまたはパスワードの確認を入力すると、ページが完全な管理フォームに更新され、クライアントが権限を変更できるようになることです。失敗したフォーム入力を強制して、クライアントを管理フォームではなく、直前に表示されていたフォームに戻します。
問題は、管理フォームとクライアント フォームの両方が 'form_for @user do |f|' を使用しているためです。フォームを定義します。レールはこの 2 つを区別できないと思います。
関連ファイルは次のとおりです。
私の管理フォーム (users#edit レンダリングされたフォーム):
= stylesheet_link_tag :universal
= form_for @user do |f|
- if @user.errors.any?
#error_explanation
%span.boldHeader= "#{pluralize(@user.errors.count, "error")} prohibited this user from being saved:"
%ul
- @user.errors.full_messages.each do |msg|
%li= msg
.fieldContainer
.field
= f.label :username
= f.text_field :username
.field
= f.label :role
= f.collection_select :role, User::ROLES, :to_s, :humanize, { :selected => :client }
.fieldContainer
.field
= f.label :password
= f.password_field :password
.field
= f.label :password_confirmation
= f.password_field :password_confirmation
.fieldContainer
.field
= f.label :first_name
= f.text_field :first_name
.field
= f.label :last_name
= f.text_field :last_name
.field
= f.label :firm_name
= f.text_field :firm_name
.fieldContainer
.field
= f.label :email
= f.text_field :email
.field
= f.label :phone
= f.text_field :phone
.actions
= f.submit 'Save'
%a.button{ :href => "/users" }Cancel
私のクライアントフォーム(レンダリングされたフォームでreset_password#edit):
= stylesheet_link_tag :universal
= form_for @user do |f|
- if @user.errors.any?
#error_explanation
%span.boldHeader= "#{pluralize(@user.errors.count, "error")} prohibited this user from being saved:"
%ul
- @user.errors.full_messages.each do |msg|
%li= msg
.fieldContainer
.field
= f.label :password
= f.password_field :password
.field
= f.label :password_confirmation
= f.password_field :password_confirmation
.actions
= f.submit 'Save'
%a.button{ :href => "/users" }Cancel
クライアント フォームの更新方法:
def update
@user = current_user
if @user.update_attributes(params[:user])
format.html { redirect_to @user, notice: 'Password successfully changed.' }
format.json { head :no_content }
else
format.json { render json: @user.errors, status: :unprocessable_entity }
format.html { redirect_to "/settings" }
end
end
管理フォームの更新方法:
def update
respond_to do |format|
if @user.update_attributes(params[:user])
format.html { redirect_to @user, notice: 'User was successfully updated' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
注: /settings は、部分的なレンダリングを含む reset_passwords#edit にルーティングします。これにより、クライアント フォームが表示されます (上記を参照)。また、routes ファイルにはリソースとして users、user_sessions、および reset_passwords があります。
最後に、これが私が生産ログで見ているものです。reset_password/_form (クライアント フォーム) で開始した後、users/_form (管理者フォーム) にロールバックされていることがわかります。
Started GET "/settings" for 127.0.0.1 at 2013-07-02 16:26:52 -0400
Processing by ResetPasswordsController#edit as HTML
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Rendered reset_passwords/_form.html.haml (4.0ms)
Rendered reset_passwords/edit.html.haml within layouts/application (14.0ms)
Rendered shared/_header.html.haml (1.0ms)
Completed 200 OK in 57ms (Views: 54.0ms | ActiveRecord: 0.0ms)
[2013-07-02 16:26:52] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
Started GET "/assets/global.css?body=1" for 127.0.0.1 at 2013-07-02 16:26:52 -0400
Served asset /global.css - 304 Not Modified (0ms)
[2013-07-02 16:26:53] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
Started PUT "/users/1" for 127.0.0.1 at 2013-07-02 16:26:58 -0400
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"9KeHrOySL3FRhSnfYtVvKl2rCz9EPBSyGmtGGasDxnA=", "user"=>{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Save", "id"=>"1"}
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", "1"]]
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
(0.0ms) begin transaction
User Exists (0.0ms) SELECT 1 AS one FROM "users" WHERE ("users"."persistence_token" = '5d1007bf94b34a7de44707e4ca432b18338f1c9ef6c5f99bf04845096a6b880057b5b43c917b9d38f790521ef62147eec3d9302471da73967048b48b4a399b18' AND "users"."id" != 1) LIMIT 1
(1.0ms) rollback transaction
Rendered users/_form.html.haml (9.0ms)
Rendered users/edit.html.haml within layouts/application (19.0ms)
Rendered shared/_header.html.haml (0.0ms)
Completed 200 OK in 80ms (Views: 61.0ms | ActiveRecord: 1.0ms)