mobiusklein
mobiusklein

Reputation: 1423

Rails Routing - :action => 'new' returns error "No route matches {:action=>"show"... in the same controller

I am writing the code for a model called "ExternalDatabase".

The model file has no code in it outside of the class declaration. I have added view pages for index, new, show, and _form .html.erb.

config/routes.rb contains the line resources :external_databases. The model contains no nested resources at this time. There are other models declared within this application, though none of them interact with this model at the moment and they are all tested and are functional and closed prior to declaring resources :external_databases.

I have a link from within the index view to new_external_database_path, which behaves exactly like {:action => "new", :controller => "external_database"} if I am following correctly.

This should theoretically load application/external_databases/new which will render _form.html.erb. The first line of _form is <%= form_for(@external_database) do |f| %>

The problem as stated in the post title occurs when using the link to /new. The url application/external_databases/new has the following error:

No route matches {:action=>"show", :controller=>"external_databases"}

When I created a data member using rails console, it was displayed properly by index and show. The same _form file is used by the edit method, and successfully edits the console-created data member. Destroy also functions.

...So why isn't it recognizing the new method?

My controller code for this model:

    class ExternalDatabasesController < ApplicationController

     def index 
      @external_databases = ExternalDatabase.all

      respond_to do |format|  
       format.html # index.html.erb
       format.json { render :json => @external_databases }
      end
     end

     # POST /external_databases
     # POST /external_databases.json

     def new 
      @external_database = ExternalDatabase.new

      respond_to do |format|
       format.html # new.html.erb
       format.json { render :json => @external_database }
      end
     end

     def show
      @external_database = ExternalDatabase.find(params[:id])

      respond_to do |format| 
       format.html # show.html.erb
       format.json {render :json => @external_database }
      end
     end

     def create
      @external_database = ExternalDatabase.new(params[:external_database])

      respond_to do |format|
       if @external_database.save
        format.html {redirect_to @external_database, :notice => "New External Database         Profile was created successfully!"}
        format.json {render :json => @external_database, :status => :created, :location => @external_database}
       else
        format.html {render :action => "new"}
        format.json { render :json => @external_database.errors, :status =>         :unprocessable_entity }
       end
      end
     end


     #GET /external_databases/1/edit
     def edit
      @external_database = ExternalDatabase.find(params[:id])
     end

     # PUT /external_databases/1
     # PUT /external_databases/1.json
     def update 
      @external_database = ExternalDatabase.find(params[:id])

      respond_to do |format|
       if @external_database.update_attributes(params[:external_database])
        format.html {redirect_to @external_database, :notice => "External Database         Profile was updated successfully!" }
        format.json {head :ok}
       else 
        format.html { redner :action => "edit" }
        format.json {render :json => @external_database.errors, :status =>         :unprocessable_entity }
       end
      end
     end


     # DELETE /external_databases/1
     # DELETE /external_databases/1.json
     def destroy
      @external_database = ExternalDatabase.find(params[:id])
      @external_database.destroy

      respond_to do |format| 
       format.html { redirect_to external_databases_rul }
       format.json { head :ok }
      end
     end

    end

Update: Added routes.rb and Views code

My routes.rb file:

    App::Application.routes.draw do

      resources :type_as do 
         resources :type_bs
         end

      resources :type_bs do 
        resources :type_as
        resources :type_cs
        end

      resources :type_cs do
       resources :type_bs
       end

      resources :external_databases

      root :to => "home#index"

    end

Views:

external_databases_form

    <%= form_for(@external_database) do |f| %>

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

index.html.erb

    <p id="notice"><%= notice %></p>
    <h1>External Databases</h1>

    <table border="1">
     <tr>
      <th>Database Name</th>
     </tr>
     <% @external_databases.each do |exdb| %>
      <tr>
       <td><%= exdb.name %></td>
       <td><%= truncate(exdb.description) %></td>
       <td><%= link_to 'Show', exdb %></td>
       <!-- link_to.... :target => "_blank" will open the url in a new window -->
       <td><%= link_to 'Visit', exdb.url, :target => "_blank" %></td>  
       <td><%= link_to 'Edit', edit_external_database_path(exdb)%></td>
       <td><%= link_to 'Destroy', exdb, :confirm => 'Are you sure?', :method => :delete %></td>
      </tr>
     <% end %>
    </table>

    <br/>
    <%= link_to 'New External Database Profile', { :action => "new", :controller => "external_databases" }%> | 
    <%= link_to 'Home', root_path %>

new.html.erb

    <h1>Creating a new External Database Profile</h1>

    <%= render 'form' %>

    <%= link_to 'Back', external_database_path %>

show.html.erb

    <p id="notice"><%= notice %></p>

    <table cellspacing="3" cellpadding="5" border="1">
     <tr> 
      <th><b>External Database Name</b></th>
      <th><b>Database ID</b></th>
     </tr>
     <tr>
      <td><%= @external_database.name %></td>
      <td><%= @external_database.id %></td>
     </tr>
     <tr colspan="2">
      <th><b>URL</b></th>
     </tr>
     <tr colspan="2">
      <td><%= @external_database.url %></td>
      <td><%= link_to 'Visit External Database', @external_database.url %></td>
     </tr>
    </table>



    <p>
     <h3>Description</h3>
     <!% @external_database.description.split.scan(/.{,60}/).each do |line| %>
      <!%= line %><br/>
     <!% end %>
    </p>

    <br /><br /><br />
    <%= link_to 'Back to External Database Index', external_databases_path %> |
    <%= link_to 'Edit', edit_external_database_path(@external_database) %> | 
    <%= link_to 'Destroy', :confirm => 'Are you sure?', :method => :delete %>

Upvotes: 4

Views: 1547

Answers (2)

Jay Killeen
Jay Killeen

Reputation: 2922

I had a similar issue to this. Followed the instructions here with no luck. At the base of my form_for code for submit I had the 'create new' and 'delete' buttons. Turns out my create new was generating an error because of a dodgy delete button :/. Anyway, I can at least comment that out to get the new button working and then focus on debugging the delete button instead.

  = f.submit "Submit", class: "btn btn-large btn-primary"
  = link_to 'Create New', new_matrix_header_path, class: 'btn btn-primary'
  -#= link_to 'Delete', matrix_header_path(@matrix_header), method: :delete, data: { confirm: 'Are you sure?'}, class: 'btn btn-danger'

I looked through the stack and found it beginning the error around line 13 of my view which was the line with my delete button.

Started GET "/matrix_headers/new" for 127.0.0.1 at 2014-10-28 21:08:48 +1000
Processing by MatrixHeadersController#new as HTML
  User Load (0.2ms)  SELECT  `users`.* FROM `users`  WHERE `users`.`id` = 1  ORDER BY `users`.`id` ASC LIMIT 1
  Rendered shared/_error_messages.html.erb (0.4ms)
  Rendered matrix_headers/_form.html.haml (21.0ms)
  Rendered matrix_headers/new.html.haml within layouts/application (22.6ms)
Completed 500 Internal Server Error in 36ms

ActionController::UrlGenerationError - No route matches {:action=>"show", :controller=>"matrix_headers", :format=>nil, :id=>#<MatrixHeader id: nil>} missing required keys: [:id]:
  actionpack (4.1.1) lib/action_dispatch/journey/formatter.rb:39:in `generate'
  actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:597:in `generate'
  actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:627:in `generate'
  actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:663:in `url_for'
  actionpack (4.1.1) lib/action_dispatch/routing/url_for.rb:155:in `url_for'
  actionview (4.1.1) lib/action_view/routing_url_for.rb:83:in `url_for'
  actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:228:in `call'
  actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:179:in `call'
  actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:268:in `block (2 levels) in define_url_helper'
   () media/jay/DATA/rails_projects/my_app/app/views/matrix_headers/_form.html.haml:13:in `block in _app_views_matrix_headers__form_html_haml__2669648707298145379_8667520'

By commenting out the delete button it now routes through to new correctly without going to the No route matches {:action=>"show" error.

Upvotes: 0

Jay H.
Jay H.

Reputation: 841

You have a typo in your new.html.erb file in your 'back' link. It should be:

external_databases_path

You can compare it with your own back link in show.html.erb above.

Fixed: new.html.erb

<h1>Creating a new External Database Profile</h1>

<%= render 'form' %>

<%= link_to 'Back', external_databases_path %>

Upvotes: 2

Related Questions