Faiz Mokhtar
Faiz Mokhtar

Reputation: 948

Nested Form with Nested Resource Rails 4

I am trying to create a nested form_for with a nested resource on Rails 4.0.3 However I've come to some problems and have spent quite a lot of time on it.

The problem is when I tried to submit the forms, the values are not save in my database. It will redirect straight through the labs#index

I have defined nested resources and labs_controller as follows.

route.rb

...    
resources :users do
  resources :labs
end

labs_controller.rb (part of it)

class LabsController < ApplicationController
  load_and_authorize_resource

  def new
    @user = User.find(params[:user_id])
    @lab  = Lab.new
  end

  def create
    @lab = Lab.new(lab_params)
    if @lab.save
      flash[:notice] = "Successfully created lab."
      redirect_to user_labs_url
    else
      render :action => 'index'
    end     
  end

  private

    def lab_params
      params.require(:lab).permit(:title, :description, 
        stages_attributes: [:id, :lab_id, :description, 
          tasks_attributes: [:id, :stage_id, :detail, :instruction, :answer ]])
    end
end

I have 3 models, Lab, Stage and Task and each one are linked through has_many relationship. I also use CanCan to handle the authorization.

lab.rb

class Lab < ActiveRecord::Base
  belongs_to :user
  has_many :stages
  resourcify

  validates :user_id, presence: true
  accepts_nested_attributes_for :stages
end

stage.rb

class Stage < ActiveRecord::Base
  belongs_to :lab
  has_many :tasks
  resourcify

  accepts_nested_attributes_for :tasks, allow_destroy: true
end

task.rb

class Task < ActiveRecord::Base
  belongs_to :stage
  resourcify

end

Here's my form partials.

_form.html.erb

<%= form_for [@user, @lab] do |f| %>
  <div class="field">
    <%= f.label :title %>
    <%= f.text_field :title %>
    <%= f.label :description%>
    <%= f.text_area :description %>
  </div>

  <%= f.fields_for :stages do |builder| %>
    <%= render "labs/partials/stage_fields", f: builder %>
  <% end %>

  <div><%= f.submit "Submit", class: "btn btn-primary" %></div>
<% end %>

_stage_fields.html.erb

<fieldset>
  <%= f.label :description %>
  <%= f.text_area :description %>
</fieldset>

<%= f.fields_for :tasks do |builder| %>
  <%= render "labs/partials/task_fields", f:builder %>
<% end %>

_task_fields.html.erb

<fieldset>
  <%= f.label :detail %>
  <%= f.text_area :detail %>
  <%= f.label :instruction %>
  <%= f.text_area :instruction %>
  <%= f.label :answer %>
  <%= f.text_field :answer %>
</fieldset>

I've gone through several questions and none of it is working for me. Eg.

I also try to follow Ryan Bates on Nested Model Form and still no luck. Hope someone could help me.

Thanks in advance!

Upvotes: 3

Views: 5188

Answers (1)

Bryan Clark
Bryan Clark

Reputation: 2602

Looking at the error logs it is probably a problem with your lab_params function. When you look at the Parameters that are passed in you want to match those with your permit options. Then check out the strong params docs for guidance on how to handle nested params.

   def lab_params
      params.require(:lab).permit(:title, :description,
        :stage => [:id, :lab_id, :description,
          :tasks => [:id, :stage_id, :detail, :instruction, :answer ]
        ]
      )
    end

I think this should get you beyond that error.

Upvotes: 1

Related Questions