多くのオプションを持つ質問モデルがあります。Rails 3レンダリングフォームで、検証に失敗した後にネストされた属性の配列がある
私が作成した私の質問コントローラ新しいアクション私のユーザーのための準備ができて5つのオプションすべてのオプションを使用してビューのIループで
def new
@question = Question.new
5.times.with_index do |index|
@question.options.build(:order => index)
end
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @question }
end
end
- form_for(@question) do |f|
.field
= f.label :title, t("question.title")
= show_errors_for(@question, :title)
= f.text_field :title
- @question.options.each do |option|
- f.fields_for :options, option do |o|
.field
= o.label :option, t("question.option_no", { :index => option.order })
= o.text_field :option
= o.hidden_field :order, :value => option.order
.actions
= f.submit t("add_question.create")
では私の質問のモデルは、この
class Question < ActiveRecord::Base
attr_accessible :title, :options_attributes
belongs_to :user
has_many :options
accepts_nested_attributes_for :options, :reject_if => proc { |attributes| attributes['option'].blank? }
validates :title, :length => { :maximum => 100 }, :presence => true
validate :min_no_of_options
def min_no_of_options
if self.options.size < 3
errors.add_to_base "Must have at least three options"
end
end
end
のように見えます
私の質問コントローラはアクションを作成します
def create
if current_user
@question = current_user.questions.build(params[:question])
else
@question = Question.new(params[:question])
end
if @question.save
redirect_to(@question, :success => t('question.flash_success'))
else
flash.now[:error] = t("question.flash_error")
render :action => "new"
end
end
フォームに2つのオプションしか入力せず、作成ボタンを押すと、検証によってモデルが保存されなくなります。どっちがいい。しかし、作成アクションが新しいアクションを再びレンダリングするとき、私が塗りつぶしたオプションフィールドだけが表示されます。空白のオプションフィールドは3つ消えました。
作成アクションの "@ question.save"を "false"に置き換えた場合の動作は同じです。これは、作成アクションで@question変数を作成する方法が、空のオプションを投げ捨てることになることを示しています。
しかし、私の質問モデルから:reject_ifを削除すると、問題のある質問の後に空のオプションが表示され、期待どおりに保存されます。 (私は自分のオプションモデルでoption属性の存在を検証しています)これは、createアクションで@question変数を作成する方法に何も問題がないことを示しています。それは空のオプションを投げ捨てていません。彼らはどこから追い出されますか?
よく似た質問が1つありましたが、その回答は私がしたいことではありません。それは私がやらなければならないことかもしれません。 rails fields_for does not render after validation error on nested form
EDIT
レールコンソールでいくつかのより多くの研究の後、私はそれが本当に空のオプションは捨てます@question変数の作成であることに気づきました。これは、問題モデルでreject_ifが定義されているために発生します。モデルからreject_ifをコメントアウトした後、空のオプションが@question変数に追加されました。
だから、データベースから空のオプションを削除するには、reject_ifを削除してafter_saveコールバックを使用する必要があると思います。このようにして、質問が保存されるまで、質問と一緒に空のオプションが表示されます。
属性名として「order」という単語を使用することをお勧めします。私は、その属性の名前を「注文」に変更した後で消えたいくつかの他の問題を引き起こしました。 – Mika