kittenchief
kittenchief

Reputation: 1255

Rails form_for Error | How to Bind Nested ActiveRecord Object to Form

I was developing a Ruby on Rails application. It has a nested route like so:

Rails.application.routes.draw do
  root 'trip_plans#index'
  resources :trip_plans do
    resources :places, except: [:show, :index]
  end
end

The trip_plans resource has a TripPlan model and the places resource has a Place model. According to the routes, the new_trip_plan_place_path is a route like /trip_plans/:trip_plan_id/places/new. The views/places/new.html.haml uses a form_for declaration to create a new place within the current trip_plan:

- content_for :title do
  %title Add a Place to Your Plan

%header.form-header
  .container.form-container
    .row
      .col-xs-12
        %h1 Add a Place
        %hr

%article
  %section
    .container.form-container
      = render 'form'

The corresponding edit.html.haml is essentially the same, calling the same _form.html.haml to render the form.

The places_controller's both new and edit action is like:

def new
  @trip_plan = TripPlan.find(params[:trip_plan_id])
  @place = @trip_plan.places.build
end

def edit
  @trip_plan = TripPlan.find(params[:trip_plan_id])
  @place = @trip_plan.places.build
end

And the _form.html.haml uses the @place like so:

= form_for @place do |f|

But as @place is a dependent ActiveRecord object, Rails is not able to figure out the correct URLs for new and edit path. It always shows a new form even on edit page.

How can I fix this?

Thanks in advance!

Upvotes: 0

Views: 169

Answers (1)

Pavan
Pavan

Reputation: 33542

It always shows a new form even on edit page

I guess the problem is this line @place = @trip_plan.places.build in your edit method.

@place = @trip_plan.places.build is nothing but @place = @trip_plan.places.new, so Rails treats @place as a new instance even on edit form.

Changing it to @place = Place.find(params[:id]) should solve your problem.

Update:

You should also change the below

= form_for @place do |f|

to

= form_for [@trip_plan, @place] do |f|

Upvotes: 1

Related Questions