7

ユーザーがプロフィールページに質問を作成するためのフォームがあります(ユーザーモデルに加えて、ネストされた回答を持つ質問モデルがあります)。ユーザー プロファイル ページ /views/users/show.html.erb から question_controller.rb の create アクションに送信します。検証されない場合、Railsのデフォルトはフォームをレンダリングすることだと思います(ユーザーが編集できるように、フォームに無効な情報を含めます)。ただし、ユーザー プロファイル ページから質問モデルのフォームを送信しているため、検証に失敗しても事前入力は行われません。ユーザーはフォームにすべての情報を再度入力する必要があります。このコンテキストで、ユーザーの表示ページのフォームに、送信前に入力された情報を入力する方法はありますか?

question_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

更新 create メソッドの末尾も変更しました

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

しかし、私はまだフォームに入力することができず、検証エラーメッセージも表示されず、フラッシュ通知のみが表示されます.

更新 ユーザーコントローラーの show メソッドは、新しい質問を作成します (ユーザーとともに)

   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>
4

2 に答える 2

1

まず、redirect_to代わりに使用するrenderとフォームが再入力されない理由は、使用redirect_toするとアクションのコントローラーロジックが実行され、使用renderするとコントローラーロジックが無視されるためです。

したがって、render :action => 'show'(「デフォルト」の動作)すると、次のようshow.html.erb@question設定されてレンダリングされます。

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

すると、アクションのコードを使用して setでredirect_to current_userレンダリングされます。show.html.erb@questionshow

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

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

あなたが使うことは本当に重要redirect_toですか?showそうである場合は、検証を行うメソッドを取得する必要があります。たとえば、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

次に、フォームがそのページを指すようにします。次のようにします。

<%= form_for(@question, url: users_path(@question.user) do |f| %>
  ...
<% end %>

(ルートの設定方法と命名方法によって異なります)。もちろん、その時点で全体が恐ろしくRESTfulではなく、少し混乱しており、間違いなくRailsのやり方ではありません。(もう 1 つの悪いオプションは、リダイレクトして get クエリを介してパラメーターを渡すことです。) 私の意見では、小さな利益のために多くを失うので、本当にお勧めできるかどうかはわかりません。

于 2013-02-28T05:30:40.580 に答える
1

現在、views/users/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

あとは、:controller=>"users", :action=>"show" にリダイレクトする前に、questions_controller に session[:question] を設定するだけです。何かのようなもの:

if @question.save
  redirect_to current_user, :notice => "Successfully created question."
else
  session[:question] = params[:question]
  redirect_to current_user
end

session[:question] を入力/使用するために、追加のシリアライゼーション/デシリアライゼーションに取り組む必要があるかもしれません。私はコンパイルしようとしなかったので、よくわかりません。

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

アプローチ (元のrender :action => "show"スキャフォールドにあり、コメントアウトしたもの) は機能しました。ユーザーに戻らず、既に配置されている変数 (@question を含む) を使用して特定の名前でテンプレートをレンダリングしたためです。 save' が呼び出されて失敗したため、内部的に検証が呼び出されてエラー オブジェクトに入力されました)。

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

if @question.save
  redirect_to current_user, :notice => "Successfully created question."
else
  @user = current_user
  render "users/show"
end
于 2013-02-28T05:31:40.113 に答える