2013-02-28 13 views
6

私はユーザーが自分のプロフィールページに質問を作成するフォームを持っています(ユーザーモデルへの追加で、質問モデルとネストされた回答があります)。ユーザーのプロフィールページ/views/users/show.html.erbからquestions_controller.rbの作成アクションに送信されます。それが検証されない場合、私はRailsのデフォルトがフォームをレンダリングすることだと思います。しかし、ユーザーのプロファイルページから質問モデル用のフォームを送信しているので、検証が失敗したときに事前挿入は行われません。ユーザーはフォーム内のすべての情報を再度入力する必要があります。このコンテキストでは、ユーザーの表示ページにフォームを提出してから送信前に入力した情報を記入する方法はありますか?検証に失敗したフォームを再入力する

questions_controller

def create 
    @question = current_user.questions.build(params[:kestion]) 

    if @question.save 
     redirect_to current_user, :notice => "Successfully created question." 
    else 
     ###render :action => 'show' 
     redirect_to current_user 

    end 
    end 

更新 私も

Redirect (: back), :notice => "something went wrong.try again" 

作成方法の終わりを変更しました。しかし、私はまだフォームが移入させることができない、と検証エラーメッセージが上がりませんいずれかを示していない、フラッシュ通知のみ。

更新 ユーザコントローラの表示方法は

def show 
     @user = User.find(params[:id]) 
     @question = Question.new 
     3.times {@question.answers.build} 

    end 

/views/users/show.html.erb

<%= form_for @question do |f| %> 
    <% if @question.errors.any? %> 
    <h2><%= pluralize(@question.errors.count, "error") %> prohibited this question 
    from being saved: </h2> 
    <ul> 
     <% @question.errors.full_messages.each do |msg| %> 
     <li> <%= msg %></li> 
    <% end %> 
    </ul> 
    <% end %> 
    <p> 
    <%= f.label :content, "Question"%> 
    <%= f.text_area :content, :class => 'span4', :rows => 1 %> 
    </p> 
    <p> 
    <%= f.label :link, "QuoraLink" %> 
    <%= f.text_field :link, :class => 'span4', :rows => 1 %> 
    </p> 
    <%= f.fields_for :answers do |builder| %> 
    <p> 
     <%= render 'answer_fields', :f => builder %> 
    </p> 
    <% end %> 
    <p><%= link_to_add_fields "Add Answer", f, :answers %></p> 
    <p><%= f.submit %></p> 
<% end %> 

answer_fields(ユーザと共に)新しい質問を作成します部分的に質問からレンダリング

<p class="fields"> 
<%= f.label :content, "Answer..." %> 

    <%= f.text_field :content, :class => 'span3', :rows => 1%> 

    <%= f.label :correctanswer, "Correct" %> 
    <%= f.check_box :correctanswer, :class => 'span1' %> 

    <%= link_to_remove_fields "remove answer", f %>  
</p> 
+0

あなたのUsersControllerではどのように 'show'メソッドが表示されますか?これは、私が理解するように、フォームをあらかじめ入力する方法です。また、views/users/show.html。{erb、haml}ビューはどのように見えますか?そこにパラメータを渡すことができますパスパラメータまたはセッション[]を介して可能性がありますいくつかの変更が必要です。 – moonfly

+0

@moonflyユーザーコントロールからのshowメソッドは、値化されていない場合はフォームを事前入力する必要がありますが、現在は行いません。私はあなたが私が示唆したコードでOPを更新しました。あなたが参照する2つの方法のいずれかで検証しないと、上記のコードを変更してフォームをあらかじめ入力する方法を教えてください。 – Leahcim

答えて

1

現在、ビュー/ユーザー/ show.rbであなたは、空の新しい質問を作成し

@question = Question.new 

を行います。次に、この空のモデルでフォームを作成します。あなたの代わりに何ができるか は次のとおりです。

if session[:question] 
    @question = @user.questions.new(session[:question]) 
    session[:question] = nil 
    @question.valid? # run validations to to populate the errors[] 
else 
    @question = Question.new 
end 

今何を行うに残って、すべてのセッション移入された[を:質問]にリダイレクトする前に、あなたのquestions_controllerで:コントローラ=>「ユーザー」、:アクション=>「ショー」。次のようなものがあります:

セッション[:質問]を追加/使用するために、シリアル化/逆シリアル化を行う必要があります。私はコンパイルしようとしなかったので、わからない。

これは、ユーザーリクエストの処理が終了すると、ユーザーブラウザがサーバーからリダイレクトステータスコードを取得し、別のページに移動して新しいリクエストを送信するためです(これは、最終的にあなたがリダイレクトされたコントローラ/アクションです)。したがって、リクエスト処理から戻るとすぐに、すべての変数が失われます。次のリクエストでは、最初から始めます。

render :action => "show"アプローチ(オリジナルの足場にあり、コメントアウトした)は、ユーザーに戻ってこなかったが、すでに配置されている変数(@ 「保存」が呼び出され、失敗したため、内部的な検証が呼び出され、エラーオブジェクトが読み込まれました)。

実際、これは別のアプローチを使用したいことがあることを私に思い出させました。 session []を介してパラメータを渡してUsersControllerにリダイレクトするのではなく、必要なすべての変数を設定し、そのコントローラからビューをレンダリングすることができます。以下のように:

if @question.save 
    redirect_to current_user, :notice => "Successfully created question." 
else 
    @user = current_user 
    render "users/show" 
end 
+0

私は2番目の提案レンダリング "users/show"を試みましたが、問題に遭遇しました。 /views/users/show.html.erbの上部には、ユーザーのリソース固有のナビゲーション部分があります。ユーザーをレンダリングするときにナビゲーション部分が表示されない/質問コントローラから表示する – Leahcim

+0

セッションソリューションは有望です(つまり質問フィールドに再入力できます)が、私は自分のshowアクションで新しい質問を作成するだけでなく、 3つの答えフィールド - 3回{@ question.answers。ビルド} - セッション情報を再作成するにはどうすればよいですか? – Leahcim

1

まず、理由renderの代わりにredirect_toを使用すると、redirect_toにコントローラのロジックが実行されますが、renderを使用するとコントローラーのロジックは無視されます。

ときにrender :action => 'show'(「デフォルト」の動作)だから、それはこのような@questionセットで、show.html.erbをレンダリング:あなたredirect_to current_user、それはあなたのshowアクションのコードを使用して@questionセットでshow.html.erbをレンダリングするとき

@question = current_user.questions.build(params[:kestion]) 

@question = Question.new 
3.times {@question.answers.build} 

これは、事前入力済みのフォームではなく新しい(空白の)フォームを取得する理由です。

は本当にです。redirect_toを使用することが重要ですか?存在する場合は、showメソッドを使用して検証を行う必要があります。あなたのルートが設定されている方法に応じて、(

<%= form_for(@question, url: users_path(@question.user) do |f| %> 
    ... 
<% end %> 
:たとえば、あなたが何かにあなたの show方法を書き換えることができます:

def show 
    @user = User.find(params[:id]) 
    if params.has_key?(:kestion) 
    @question = @user.questions.build(params[:kestion]) 
    else 
    @question = Question.new 
    3.times {@question.answers.build} 
    end 
end 

、その後のようなもので、そのページでフォームのポイントを作ります名前を付けられた)。もちろん、その時点では、全体がひどくun-RESTfulになってしまい、ちょっと混乱してしまいますし、もちろんRailsのやり方ではありません。 (他の悪い選択肢は、リダイレクトしてgetクエリを介してパラメータを渡すことです)。私の意見では、マイナーな利益のために多くを失い、私は本当にそれをお勧めしているかどうかはわかりません。

+0

私は 'ひどくun-RESTfulな'コメントに同意します。 @Michael、あなたの意図が正しいとすれば、UIを改善し、質問をユーザーフォームで編集できるように思えます。それを行うと、次の論理的なステップを作成し、UsersController#updateメソッドの質問を保存/検証するのが理にかなっているでしょう。 QuestionsControllerをすべて削除し、UserControllerにUserとQuestionの両方のモデルを処理させます。 – moonfly

関連する問題