Swaathi Kakarla
Swaathi Kakarla

Reputation: 2443

Nested routes redirecting to create action with wrong route

I've created nested routes for a model called Userfolder. The routes are mapped like this:

Rake Routes

userfolder_userfolders POST   /userfolders/:userfolder_id/userfolders(.:format)     userfolders#create
new_userfolder_userfolder GET    /userfolders/:userfolder_id/userfolders/new(.:format) userfolders#new

Which is exactly the way I want it. But when I create a new Userfolder, Rails is redirecting the create action to "/userfolders" and not "/userfolders/:userfolder_id/userfolders". It is still following the initial Rails scaffolding routes.

Is there a way to change this? Or have I missed out on something entirely?

EDIT 1: Here is my Userfolder controller code.

class UserfoldersController < ApplicationController


before_action :set_userfolder, only: [:show, :edit, :update, :destroy]
  before_action :set_parentfolder, except: [:show, :edit, :update, :destroy, :index]

  # GET /userfolders
  # GET /userfolders.json
  def index
    if Userfolder.first.nil?
      Userfolder.create(:name => 'root', :parent_id => 0)
    end
    redirect_to Userfolder.first
  end

  # GET /userfolders/1
  # GET /userfolders/1.json
  def show
  end

  # GET /userfolders/:userfolder_id/userfolders/new(.:format)
  def new
    @userfolder = @parentfolder.children.build
  end

  # GET /userfolders/1/edit
  def edit
  end

  # POST /userfolders/:userfolder_id/userfolders
  def create
    @userfolder = @parentfolder.children.build(userfolder_params)

    respond_to do |format|
      if @userfolder.save
        format.html { redirect_to userfolder_path(@parentfolder.id), notice: 'Userfolder was successfully created.' }
      else
        render :action => 'new'
      end
    end
  end

  # PATCH/PUT /userfolders/1
  # PATCH/PUT /userfolders/1.json
  def update
    respond_to do |format|
      if @userfolder.update(userfolder_params)
        format.html { redirect_to @userfolder, notice: 'Userfolder was successfully updated.' }
      else
        render :action => 'edit'
      end
    end
  end

  # DELETE /userfolders/1
  # DELETE /userfolders/1.json
  def destroy
    parent_folder = @userfolder.parent
    @userfolder.destroy
    respond_to do |format|
      format.html { redirect_to parent_folder, notice: 'Userfolder was successfully destroyed.' }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_userfolder
      @userfolder = Userfolder.find(params[:id])
    end

    def set_parentfolder
      @parentfolder = Userfolder.find(params[:userfolder_id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def userfolder_params
      params.require(:userfolder).permit(:name, :parent_id)
    end
end

This is my routes.rb file:

Rails.application.routes.draw do
  resources :userfiles

  # The priority is based upon order of creation: first created -> highest priority.
  # See how all your routes lay out with "rake routes".

  # You can have the root of your site routed with "root"
  root 'userfolders#index'

  resources :userfolders, :shallow => true, :except => [:new, :create] do
    resources :userfolders, :only => [:new, :create]
  end

EDIT 2: This is the console output: Console

Upvotes: 2

Views: 766

Answers (1)

Swaathi Kakarla
Swaathi Kakarla

Reputation: 2443

So the issue was with the _form.html.erb like I suspected.

This is the create controller:

  def create
@userfolder = @parentfolder.children.build(userfolder_params)

respond_to do |format|
  if @userfolder.save
    format.html { redirect_to @parentfolder, notice: 'Userfolder was successfully created.' }
  else
    render :action => 'new'
  end
 end
end

And here is the _form.html.erb:

    <%= form_for([@parentfolder, @userfolder]) do |f| %>
  <% if @userfolder.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@userfolder.errors.count, "error") %> prohibited this userfolder from being saved:</h2>

      <ul>
      <% @userfolder.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :parent_id %><br>
    <%= f.number_field :parent_id %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

By adding the <%= form_for([@parentfolder, @userfolder]) do |f| %>, I'm telling Rails to redirect to /userfolders/:userfolder_id/userfolders. Instead of redirecting to /userfolders.

Upvotes: 1

Related Questions