2012-04-11 14 views
7

私はRails 3でフォームウィザードを使用しています。基本的にホテルオブジェクトを作成し、そのすべてが完了したらその場所オブジェクトを作成しますホテル。レール3:インスタンス変数はリダイレクト後に利用できません

def create 
    @hotel = Hotel.new(params[:hotel]) 

    respond_to do |format| 
     if @hotel.save 
     @location = Location.new 
     format.html { redirect_to '/set_location'} 
     else 
     format.html { render action: "new" } 
     end 
    end 
    end 

次に、 '/ set_location'ページには、場所を設定するフォームがあります。しかし、@locationインスタンス変数のhtml.erbに'undefined method model_name for NilClass:Class'というエラーが表示されています。

これは、redirect_toの代わりにレンダリング '/ set_location'を使用したときと同じように、本当に変です。しかし、レコードの重複を避けるためにredirect_toメソッドを使用したいと思います。

ありがとうございました。

+1

重複エラー提出は何ですか? redirect_toは別のコントローラアクションにリダイレクトします。そこにインスタンス変数が設定されていなければ、失敗します。 – shime

+0

その_record_ submissionが重複しています - 基本的にデータベースにデータが重複しています。それは、私が別のコントローラアクションを実行すると、コントローラの1つのアクションでインスタンス変数が失われることを意味しますか?これらのアクションの間に変数を渡す方法はありますか?多分セッションに入れる?悪い練習なし? – Ger

答えて

15

HTTPはステートレスな仕様です。リクエスト間で状態を共有したい場合は(リードを別のリクエストにリダイレクトする)、sessionハッシュを使用する必要があります。

session[:hotel_id] = @hotel.id 

そしてあなたが/set_locationであなたのHotelをこのように取得:このよう

Hotel.find(session[:hotel_id]) 
+1

@locationの不足を解決するにはどうすればよいでしょうか? – Nobita

+0

それは役に立ちません。要求間で変数を渡すことはできません。私は作者が考えを持っていると思う:セッションを使う。 – jdoe

1

私はあなたが何をしたいと考えています:

  1. コントローラとアクションが応答する識別"/ set_location"リクエストに追加します。
  2. あなたはこの行が欠けていることがわかります@location = Location.new。そこに作成する必要があります。 Railsの中

インスタンス変数は、多くの場合、あなたのコントローラとビューの間で情報を渡すために使用され、をレンダリングする際、あなたはそのエラーを取得しない理由ですされています。 Railsビューは、コントローラからのインスタンス変数について知っています。

しかし、あなたはリダイレクトを行っているので、あなたは何もわからない別のコントローラを呼び出しています@locationです。

0

ノビータの回答は最も包括的な回答であり、OPの正確な質問に答えていると思います。投票してください(@Ger)。

jdoeの答えでは、「要求」はビュー(またはテンプレート)の要求として解釈できるため、彼の説明では「要求」を使用することについて、より多くの説明を期待しています。 )他のフレームワークでは、そのレールの面で読んだとき、この文は(自分を含め)新しいRailsの開発者に少し誤解を招くかもしれません:

「変数は、リクエスト間で渡すことができない私は、著者が得たと思います。 アイデア:セッションを使用する。

「レンダリング」を使用してコントローラからビュー/テンプレートをリクエストすると、実際には変数が渡されます。したがって、コントローラメソッドがビューをレンダリングする場合、そのビューにはそのコントローラで定義した@variableの知識があります。

さらに、セッションを使用することは、実際にはリクエスト間で変数を渡す唯一の方法ではありません。(routes.rbをファイルに)

を考えてみましょう:あなたは、変数をキャッチするためにあなたのルートにリダイレクト変更することができます

match 'surveys/result(/:id)' => "surveys#result", via: [:get], as: 'surveys_result' 

を今、「調査」コントローラ「結果」アクションメソッドでは、あなたが:idを持っていますパラメータ。 params[:id]と呼びます(たとえば、このIDを持つデータベース内のオブジェクトを見つけるには)。私は、URI/URLから:idを隠す方法もあると信じています。あなたがそこにそれを見ることを望まない場合に備えて。

@shime: "duplicate entry"の質問に関連して、私はOPがPOSTリクエストのビューをレンダリングすることを指していたと考えています。もしPOSTが成功したとしたら、すでにフォームを提出した後にページをリフレッシュするたびに、重複したエントリーをデータベースに提出するかもしれません(リダイレクトメソッドはこれが起こらないようにするため、標準的な方法ですあなたのPOSTリクエストからのルート)と私が見つけたこの段落は、両方の実装に何が起こるかの明確な説明のいずれかになります。

https://gist.github.com/jcasimir/1210155#redirect

関連する問題