Nastya Soroko
Nastya Soroko

Reputation: 11

Rails Routing Error :action => 'new' returns error “No route matches {:action=>”show" in the controller

Model "Project" was generated by scaffolding.

config/routes.rb contains the line resources :projects.

I have a link from the index view to new_project_path.

Problem is with the link to /new. The url application/project/new has the following error:

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

It was working but now isn't working, i don't know why. Any ideas?

class ProjectsController < ApplicationController
  # GET /projects
  # GET /projects.json
  def index
    @projects = Project.paginate(:page=>params[:page],:per_page=>15)

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

  # GET /projects/1
  # GET /projects/1.json
  def show
    @project = Project.find(params[:id])
    @[email protected](:page=>params[:page],:per_page=>15)

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

  # GET /projects/new
  # GET /projects/new.json
  def new
    @project = Project.new

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

  # GET /projects/1/edit
  def edit
    @project = Project.find(params[:id])
  end

  # POST /projects
  # POST /projects.json
  def create
    @project = Project.new(params[:project])

    respond_to do |format|
      if @project.save
        format.html { redirect_to projects_path, notice: 'Project was successfully created.' }
        format.json { render json: @project, status: :created, location: @project }
      else
        format.html { render action: "new" }
        format.json { render json: @project.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /projects/1
  # PUT /projects/1.json
  def update
    @project = Project.find(params[:id])

    respond_to do |format|
      if @project.update_attributes(params[:project])
        format.html { redirect_to @project, notice: 'Project was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @project.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /projects/1
  # DELETE /projects/1.json
  def destroy
    @project = Project.find(params[:id])
    @project.destroy

    respond_to do |format|
      format.html { redirect_to projects_url }
      format.json { head :no_content }
    end
  end

  def sort_tasks
    project = Project.find(params[:id])
    tasks = project.tasks
    tasks.each do |task|
      task.position = params['task'].index(task.id.to_s) + 1
      task.save
    end
    render :nothing => true
  end

end

routes.rb:

Taska::Application.routes.draw do
  resources :projects
  resources :tasks

  root :to => 'projects#index'

  match ':controller(/:action(/:id))(.:format)'
end

_form.html.erb:

<%= form_for @project, :html => { :class => 'form-horizontal' } do |f| %>
  <div class="control-group">
    <%= f.label :title, :class => 'control-label' %>
    <div class="controls">
      <%= f.text_field :title, :class => 'text_field' %>
    </div>
  </div>
  <div class="control-group">
    <%= f.label :description, :class => 'control-label' %>
    <div class="controls">
      <%= f.text_area :description, :class => 'text_area', rows: 5 %>
    </div>
  </div>

  <div class="form-actions">
    <%= f.submit nil, :class => 'btn btn-primary' %>
    <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
                project_path(@project), :class => 'btn' %>
  </div>
<% end %>

index.htm.erb:

<%- model_class = Project -%>
<div class="page-header">
  <h3><%=t '.title', :default => model_class.model_name.human.pluralize %></h3>
  <%= link_to t('.new', :default => t("helpers.links.new")),
              new_project_path,
              :class => 'btn btn-primary' %>
</div>

<table class="table table-striped">
  <thead>
    <tr>
      <th><%= model_class.human_attribute_name(:title) %></th>
      <th>Tasks count</th>
      <th>Updated at</th>
    </tr>
  </thead>
  <tbody>

    <% @projects.each do |project| %>
      <tr>
        <td><%= link_to project.title, project_path(project) %></td>
        <td><%= project.tasks.size %></td>
        <td><%= project.updated_at %></td>
      </tr>

    <% end %>

  </tbody> 

</table>
<%= will_paginate @projects %>

show.html.erb:

<%- model_class = Project -%>
<div class="page-header">
  <h1><%=t '.title', :default => @project.title %></h1>
  <h4><%= @project.description %></h4>
  <%= link_to t('.edit', :default => t("helpers.links.edit")),
                      edit_project_path(@project), :class => 'btn btn-primary' %>
          <%= link_to t('.destroy', :default => t("helpers.links.destroy")),
                      project_path(@project),
                      :method => :delete,
                      :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
                      :class => 'btn btn-primary btn-danger' %>

<h2>Tasks:</h2>

<%= link_to t('.new', :default => t("helpers.links.new")),
            new_task_path(:project_id => @project),
            :class => 'btn btn-primary' %>
</div>

<table class="table table-striped">
  <thead>
  <tr>
    <th></td>
    <th><%= model_class.human_attribute_name(:type) %></th>
    <th><%= model_class.human_attribute_name(:title) %></th>
    <th><%= model_class.human_attribute_name(:status) %></th>
    <th><%= model_class.human_attribute_name(:updated_at) %></th>
  </tr>
  </thead>
  <tbody id="tasks_list">
  <% @tasks.each do |task| %>
      <tr id="task_<%= task.id %>" class="handle" >
        <td><%= link_to "open task",task_path(task) %></td>
        <td><%= task.type.name %></td>
        <td><%= task.title %></td>
        <td><%= task.status.name %></td>
        <td><%= task.updated_at %></td>
      </tr>
  <% end %>
  </tbody>
</table>
<%= will_paginate @tasks %>
<input type="hidden" id="project_id" value='<%[email protected]%>'>

new.html.erb :

<%- model_class = Project -%>
<div class="page-header">
  <h1>New project</h1>
</div>
<%= render :partial => 'form' %>

Upvotes: 1

Views: 1488

Answers (4)

abigure
abigure

Reputation: 51

If your "_form.html.rb" is also used by "edit.html.erb", you can rewrite as following:

  ...
  <div class="form-actions">
    <%= f.submit nil, :class => 'btn btn-primary' %>
    <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
            (@project.id.nil? ? projects_path : project_path(@project)), :class => 'btn' %>
  </div>
<% end %>

If you edit a existing record in table projects which has id = 10020, url helper project_path(@project) can generate

<a href="/projects/10020" class="btn">Cancel</a>

in html.

If you're creating new, url helper projects_path can generate

<a href="/projects" class="btn">Cancel</a>

in html.

Upvotes: 0

Aleks
Aleks

Reputation: 5330

Have you tried to restart the server?

If you want to be sure if some routes are appearing or which routes you can use, run in console:

rake routes

if it lists route to projects/show, then it is possible that you have just to restart server. But if it is not, problem could be in spelling or, even if you changed match in routes

EDIT

I have just noticed, that in new action inside your project controller, you have put respond

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

Delete those lines. It should look like:

def new
    @project = Project.new

end

EDIT 2:

I realized what you wanted to do. As I can see you are beginner, so I can assume that you wanted to create new object in new action, and transfer that to new form, and to return to new project, when you hit 'cancel', but that is not how rails functions. You shouldn't use @project object in your action and to respond that to html. And use of that @project from new action is causing all the problems. Remove @project from action, and all usage of @project in new action (in view also)

Upvotes: 0

abhijit
abhijit

Reputation: 1968

As pointed by chris, your cancel link is pointing to a wrong action, and its looking for a /projects/show which is not present.

"show" has a format of projects/:id/show, which happens to be member route. Show is a inherited resource of type member. That is the error!

Upvotes: 0

Christoph Petschnig
Christoph Petschnig

Reputation: 4157

You might want to write in _form.html.rb:

  ...
  <div class="form-actions">
    <%= f.submit nil, :class => 'btn btn-primary' %>
    <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
                projects_path, :class => 'btn' %>
  </div>
<% end %>

(Changing project_path(@project) to projects_path to take you to the index page.)

You where trying to link to the show page of an object that is not in the database. What the error message wants to say is "You told me to link to the show page, but I have no id." I admit this is confusing.

Upvotes: 1

Related Questions