tuna
tuna

Reputation: 105

nested routing fails on create

Locations have listings. From the locations index, I want the user to be able to add a new listing (which belongs to that location) and then be redirected to the updated index.

My routes are as follows:

match 'listings/search' => 'listings#search'
resources :locations do
   resources :listings
end
resources :locations
resources :listings
match "listings/:location" => 'listings#show'

Here is the form for the listing:

<%= form_for(@listing, :url=>"/locations/#{@location_id}/listings") do |f| %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Which I think should call the create method in listings_controller:

def create
  @location= Location.find(params[:location_id])
  @location_id = @location.id
  @listing = @location.listings.create(params[:listing])

  respond_to do |format|
    if @listing.save
      redirect_to location_listings_path(@location_id)
    else
      format.html { render action: "new" }
    end
  end
end

When I press submit, it redirects to /locations/1/listings which is exactly what I want. But the window is blank. If i press refresh (access locations/1/listings any other time), it shows the index properly.

Upvotes: 0

Views: 43

Answers (2)

Thomas Klemm
Thomas Klemm

Reputation: 10856

Some reworking done:

# config/routes.rb
resources :locations do
   resources :listings
   get :search, on: :collection # will be directed to 'locations#search' automatically
end

resources :listings

The form url can be used like this or the way Peter proposes:

<%= form_for(@listing, url: location_listings_path(@location)) do |f| %>
  <div class="actions">
  <%= f.submit %>
  </div>
<% end %>

And your controller can be cleaned up as well:

# app/controllers/listings_controller.rb
def create
  @location = Location.find(params[:location_id])
  @listing = @location.listings.build(params[:listing])

  if @listing.save
    redirect_to location_listings_path(@location_id)
  else
    render action: :new
  end
end

Upvotes: 0

Peter de Ridder
Peter de Ridder

Reputation: 2399

You could also change your form_for to:

<%= form_for([@location, @listing]) do |f| %>

So you don't have to add the :url part.

Upvotes: 1

Related Questions