The resulting Rails 3 form with an array of nested attributes after a validation failure

I have a question model that has many options.

In my new question controller, I create five options that are ready for my user.

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 

In the view, I look through all the options

 - 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") 

My question model is as follows

 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 

And my question controller creates an action

 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 

Now, when I enter only two parameters in the form and click the create button, the check does not allow me to save the model. And this is good. But when the create action creates a new action again, only the parameter fields that I filled out appear. Three parameter fields that remained empty have disappeared.

If I replaced "@ question.save" in my create action with "false", the behavior will be the same. Thus, this suggests that something in the way I create the @question variable in the create action is responsible for deleting my empty parameters.

But if I delete: reject_if from my question model instead, empty options appear after the failure problem persists as expected. (I have presence validation for the option attribute in my parameter model). This tells me that there is nothing wrong with how I create the @question variable in the create action. This does not throw away empty options. So where are they kicked out?

There was one rather similar question, but there is no answer there that I would like to do. Although this may be something I have to do. rails fields_for does not display nest form validation after error

EDIT

After another study with the rails console, I noticed that this is really creating the @question variable, where empty options are thrown. This is because I have the reject_if parameter defined in the question model. After commenting out the reject_if parameter from the model, empty options were added to the @question variable.

So, I think I need to remove reject_if and use the after_save callback to destroy the empty parameters from the database. This way, I will have empty options related to the question until the question is saved.

+4
source share
1 answer

I answer my question because I solved the problem.

Empty “options” were removed from the “question” due to reject_if in the “question” model. The reject_if instruction was applied when the code below was executed, and therefore the empty "options" were deleted.

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

I replaced reject_if with an after_save callback, which removes parameters that were empty.

+3
source

All Articles