2

エラーを生成する可能性があるフォームの作成アクションがあります (つまり、名前がありません)、その後リダイレクトされます。

問題は、リダイレクトが発生すると、これらのフォーム エラーが失われることです。これらのフォームエラーをセッションに渡して元のフォームに戻すにはどうすればよいですか (元の error_messages 動作のように、以前の詳細を入力する必要があります)。

ありがとう!


コード:

def create
  @contact = Contact.new(params[:contact])
  if @contact.save
    flash[:notice] = "Sent."
  else
    flash[:notice] = "Error."
  end
end
4

2 に答える 2

5

Rails での規則は、リダイレクトを行うのではなく、元のアクションのビューをレンダリングすることです。したがって、コードは次のようになります。

def create
  @contact = Contact.new(params[:contact])
  if @contact.save
    flash[:notice] = 'Sent.'
    redirect_to @contact
  else
    flash.now[:notice] = 'Error.'
    render :new
  end
end

アクションのために追加の設定が必要な場合はnew、共通コードをプライベート メソッドに抽出し、before_filterと の両方newで呼び出しますcreate

于 2010-04-04T03:00:47.553 に答える
3

これは、私自身が苦労してきたトリッキーな問題です。最初の質問は、エラーが見つかったときにリダイレクトする必要があるのはなぜですか? エラーがある場合にアクションを強制的にレンダリングすることは、Rails フレームワークの設計者が複雑さと使いやすさを考慮して意識的に決定したものです。

ここに大きな問題があります。アクションで params を使用してモデルのインスタンスを作成すると、オブジェクトの検証が失敗し、別のアクションにリダイレクトすることにします。別のアクションにリダイレクトする前に、モデル インスタンスの現在の状態をセッションに保存してから、アクション :foo にリダイレクトする必要があります。アクション :foo では、属性の更新を再試行し、インスタンス変数を介してエラーをビューに渡す必要があります。ここでの問題は、コントローラーでアクションを結合していることです。これは悪いことです (1 つのアクションが他のアクションに依存しています)。他にもたくさんの問題があり、それらについて永遠に書き留めることができますが、これを 1 つのリソースに対してのみ行う必要がある場合は、次のようにします。

config/routes.rb

map.resources :things, :member => { :create_with_errors => :get }

things_controller.rb

def new
  @thing = Thing.new
end

def create
  @thing = Thing.create(params[:thing])
  if @thing.save
    redirect_to things_path
  else
    session[:thing] = @thing
    redirect_to create_errors_thing_path(@thing)
  end
end

def create_with_errors
  @thing = session[:thing]
  @errors = @thing.errors
  render :action => :new
end

アプリ/ビュー/もの/new.html.erb

<% if defined?(@errors) %>
<% #do something with @errors to display the errors %>
<% end %>

<!-- render the form stuff -->

私はあなたが何を考えているか知っています...これは恐ろしいです。信じてください、私はこの問題に対処するために多くの試みをしてきましたが、Rails 開発者が選択したメカニズムがエラーに対処するための最良かつ最も簡単な方法であることに気づきました。

于 2010-04-04T02:58:43.197 に答える