2011-02-07 13 views
1

現在、Railsがどのように動作しており、検証結果に応答しているかに問題があります。私はユーザー登録フォームを持っています。ユーザーは2つの異なる場所でこのフォームに当てることができます。彼らはホームページやusers/newからフォームにヒットすることができます。どちらの書式も同じ場所に投稿しますが、私はそれをDRYにしています。Railsバリデーション条件付きリダイレクト

users/newページは期待どおりに動作します。ユーザーに検証の問題がある場合は、フォームが返され、入力されます。どこに問題があるのか​​はホームページにあります。ユーザーに確認の問題がある場合、users/newページにリダイレクトされます。私は多くの場合、ホームページにいるときに同じページにユーザーを戻し、そこに検証結果を表示することをお勧めします。コントローラに、ユーザーがいたフォームにリダイレクトする方法はありますか?

def create 
    @user = User.new(params[:user]) 

    respond_to do |format| 
    if @user.save 
     format.html { redirect_to(@user, :notice => 'User was successfully created.') } 
     format.xml { render :xml => @user, :status => :created, :location => @user } 
    else 
     format.html { render :action => "new" } # I'm thinking I can do something here? 
     format.xml { render :xml => @user.errors, :status => :unprocessable_entity } 
    end 
    end 
end 

私は、ユーザーのURLにリダイレクトするrender :action => 'new'行を変更しようとしたが、それは働いていません。私は行方不明のものがありますか?

+0

したがって、ユーザーがホームページで検証の問題が発生した場合、リダイレクトされず、間違った表示がレンダリングされます...正しいのですか? – dontangg

+0

正しい。検証の問題により、ユーザーは常にユーザーフォームに移動します。元のフォームがインデックスページにあったとしても。残念ながら、ユーザーは2つの場所から登録することができます。 –

答えて

2

まず、私はそれがこのようなものを持つから来たことをコントローラとアクションとに投稿されたURLにクエリ文字列パラメータを追加します。

# Using form_tag 
<%= form_tag user_path(@user, :controller_name => controller.controller_name, :action_name => controller.action_name) do %> 

# Using form_for 
<%= form_for @user, :url => user_path(@user, :controller_name => controller.controller_name, :action_name => controller.action_name) do %> 

その後、あなたはcreateアクションでその行を更新することができますこのようなあなたのコントローラで:

render '#{params[:controller_name]}/#{params[:action_name]}' 

更新

私はちょうど目を実現しました上記のコードを使用すると、最初に検証が失敗したときに正しいビューがレンダリングされますが、検証がもう一度失敗すると、users/createビューをレンダリングしようとします。これが目的のルートである場合は、ビュー内でcontroller.controller_nameなどを使用しないでくださいが、@controller_nameを正しく割り当てて、代わりにその変数を使用してください。しかし、これはXavierによる「過度の」コメントにのみ追加されます。

+0

私もこれについて考えていて、私のコードで同じ問題に遭遇しました。検証は2回失敗し、私の場所は永遠に失われます。 ':controller_name => controller.controller_name'と':controller_name => params [:controller_name] ||を置き換えて、動作させることができます。 params [:controller] '(そして':action'と同様に)ので、前回のコントローラとアクションを使用しません。私はまだそれが多くのコードだと思うが、それは動作し、私は確かに簡単な方法を考えることができない... Upvote - 歓声! –

0

はそれは、それが唯一の成功のためにredirect_to(request.env["HTTP_REFERER"])

おっとための速記作品だredirect_to :back
を試してみてください。申し訳ありません

よく、その後、彼は(request.env ["HTTP_REFERER"]を見て)、それぞれのアクションをレンダリングして彼が来たブロック(format.htmlの後)をチェックする必要があります。

+0

それは正しいページに私を連れて行くが、そのとき検証は設定されません。リダイレクトするとエラーメッセージが消えてしまいました。 –

2

アートは正しいですが、リダイレクトを使用することはできません。コントローラで設定されているインスタンス変数@userが必要です。新しいHTTPリクエストでは失われます。新しい、きれいなコントローラインスタンス)。

しかし、あなたはリファラ情報を自分で使用して、レンダリングするために右のページを選択することを使用することができます。

render :action => (request.referer =~ /\/users\/new/)? :new : :index 

注:私はそれを掲示している間にポップアップ別の答えは、古いコントローラ/アクションフィールドを追加提案しますあなたのフォームには、それは私に過剰なもののようです - あなたはすでにrequest.refererに必要なすべての情報を持っています。

希望に役立ちます!

+0

私はあなたに同意します。それは過労かもしれません。ただし、ルートの名前(/ users/new)を気にする必要はありませんが、変更する可能性はありません(/ users/signup、/ users/registerなど)。また、2つ以上のページでこの作業を簡単に行うことができます。繰り返しますが、そうする必要は決してないかもしれませんが、可能性があります。それでも、私は過剰殺戮の主張を完全に理解しています。今私は6歳です。 – dontangg

+0

@dontanggそれは良い点です - 通常の "Railsy" URLを使ったアクションでさえ、それは数ヶ月のうちに起こるのを待っている厄介な謎のバグです。もしあなたが 'old_params =私はGoogleのためにこれをぶち壊していますが、有望に見えません...乾杯! –

+0

ちょうど何かが見つかりました。あなたは 'path = ActionController :: Routing :: Routes.recognize_path(request.referer)'を使うことができます。次に、#{path [:controller]} /#{path [:action]} ''をレンダリングするだけです。しかし、2回目の検証が失敗するのを心配する必要はありますか?それで、そのアクションは 'create'でしょうか? PS。私はこれが 'ActionDispatch :: Routing'なので、Rails 3ではこれが動作しないと思います。 – dontangg

関連する問題