Search code examples
ruby-on-railsrubyfriendly-id

No route matches ... missing required keys


I have two controllers and models Projects and Schemas. Schemas belongs_to projects. Projects has_many schemas. I am looking for http://localhost:3000/projects/SLUG-PROJECT/schemas/SLUG-SCHEMA.

Following is my SchemaController code:

class Projects::SchemasController < ApplicationController
  before_action :set_schema, only: [:show, :edit, :update, :destroy]
  before_action :set_project, only: [:index, :show, :new, :edit, :update, :destroy]


  def index
    @schemas = Schema.all
  end


  def show
  end


  def new
    @schema = Schema.new
  end


  def edit
  end


  def create
    @schema = Schema.new(schema_params)

    respond_to do |format|
      if @schema.save
        format.html { redirect_to project_url(@schema.project_id), notice: 'Schema was successfully created.' }
      else
        format.html { render :new }
      end
    end
  end


  def update
    respond_to do |format|
      if @schema.update(schema_params)
        format.html { redirect_to project_url(@schema.project_id), notice: 'Schema was successfully updated.' }
      else
        format.html { render :edit }
      end
    end
  end



  def destroy
    @schema.destroy
    respond_to do |format|
      format.html { redirect_to project_url(@schema.project_id), notice: 'Schema was successfully destroyed.' }
    end
  end




  private

    def set_schema
      @schema = Schema.find(params[:id])
    end

    def set_project
      @project = Project.friendly.find(params[:project_id])
    end


    def schema_params
      params.require(:schema).permit(:number, :identification, :reference, :name, :description, :author, :controller, :priority, :notes, :status, :cycle, :slug, :project_id)
    end

end

This is my code:

respond_to do |format|
  if @schema.update(schema_params)
    format.html { redirect_to project_url(@schema.project_id), notice: 'Schema was successfully updated.' }
  else
    format.html { render :edit }
  end

It works for index and show pages, but I get the following error for update, edit, and destroy:

ActionController::UrlGenerationError in Projects::SchemasController#update

No route matches {:action=>"show", :controller=>"projects", :id=>nil} missing required keys: [:id]

Can anybody help me figure out what is going on?


Solution

  • What you’re looking for is nested routes. In this case you could include this route declaration:

    resources :projects do
      resources :schemas
    end
    

    In addition to the routes for projects, this declaration will also route schemas to an SchemasController. The schema URLs require a project:

    /projects/:project_id/schemas/:id
    

    This will also create routing helpers such as project_schemas_url and edit_project_schema_path. These helpers take an instance of Project as the first parameter: project_schemas_url(@project).

    And remember to always instantiate schemas on an existing project, say:

    @project.schemas.build