Search code examples
ruby-on-railsupdatessimple-formnested-formshas-many

Rails Nested Form doesn't update. strong_params are setted right


Nested form (with simple_form gem) creates the record, but doesn't want to update it.

Checklist has many questions. Question belongs to one checklist.

All strong params are setted.

So, in controller:

...
  before_action :set_checklist, only: [:show, :edit, :update, :destroy]
...
  def new
    @checklist = Checklist.new
    @checklist.questions.build
  end

  def create
    @checklist = Checklist.new(checklist_params)

    if @checklist.save
      redirect_to checklists_url, notice: 'Checklist was successfully created.' 
...
  def edit
  end

  def update
    if @checklist.update(checklist_params)
      redirect_to @checklist, notice: 'Checklist was successfully updated.'
    else
      render :edit 
    end
  end  
...
  private
    def set_checklist
      @checklist = Checklist.find(params[:id])
    end  

    def checklist_params
      params
        .require(:checklist)
        .permit(:title, :description,
          questions_attributes: Question.attribute_names.map(&:to_sym).push(:_destroy))
    end 

in view form:

= simple_form_for(@checklist) do |f|
  = f.error_notification
  .form-inputs
    = f.input :title
    = f.input :description  
...
    %tbody.questions
      = f.simple_fields_for :questions do |builder|
        = render 'question_fields', f: builder
...

in _question_fields:

%tr.nested-fields
  %td
    = link_to_remove_association "remove", f, class: 'btn btn-primary btn-xs' 

  %td
    = f.input :title, label: false
  %td
    = f.input :description, label: false

in checklist model:

has_many :questions, dependent: :destroy

  accepts_nested_attributes_for :questions, 
          allow_destroy: true, 
          reject_if: proc { |att| att['title'].blank? } 

in question model:

  belongs_to :checklist, optional: true

Thank you


Solution

  • %tr.nested-fields
      %td
        = link_to_remove_association "remove", f, class: 'btn btn-primary btn-xs' 
    
      %td
        = f.input :title, label: false
      %td
        = f.input :description, label: false
    

    your partial is missing = f.hidden_field :id and = f.hidden_field :_destroy