Ruby Rails ActionController::UrlGenerationError in Friends#new missing required keys: [:id]

81 Views Asked by At

I am seeing the following error while trying to access the new page of my new model in rails 6.1 after I upgraded rails to version 6.1 from 5.2 and ruby to 2.7 from 2.5 respectively.

No route matches {:action=>"show", :controller=>"friends", :format=>nil, :id=>#<Friend id: nil, first_name: nil, last_name: nil, created_at: nil, updated_at: nil>}, possible unmatched constraints: [:id]

here is my friends model

class Friend < ApplicationRecord
end

here is the friends controller

class FriendsController < ApplicationController
  before_action :set_friend, only: [:show, :edit, :update, :destroy]

  # GET /friends
  def index
    @friends = Friend.all
  end

  # GET /friends/1
  def show
  end

  # GET /friends/new
  def new
    @friend = Friend.create
  end

  # GET /friends/1/edit
  def edit
  end

  # POST /friends
  def create
    @friend = Friend.new(friend_params)

    if @friend.save
      redirect_to @friend, notice: 'Friend was successfully created.'
    else
      render :new
    end
  end

  # PATCH/PUT /friends/1
  def update
    if @friend.update(friend_params)
      redirect_to @friend, notice: 'Friend was successfully updated.'
    else
      render :edit
    end
  end

  # DELETE /friends/1
  def destroy
    @friend.destroy
    redirect_to friends_url, notice: 'Friend was successfully destroyed.'
  end

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

    # Only allow a list of trusted parameters through.
    def friend_params
      params.require(:friend).permit(:first_name, :last_name)
    end
end

here is the new friends view which is throwing the error

<h1>New Friend</h1>

<%= render 'form', friend: @friend %>

<%= link_to 'Back', friends_path %>

and here is the _form which the view is referring to

<%= form_with(model: friend) do |form| %>
  <% if friend.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(friend.errors.count, "error") %> prohibited this friend from being saved:</h2>

      <ul>
        <% friend.errors.each do |error| %>
          <li><%= error.full_message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :first_name %>
    <%= form.text_field :first_name %>
  </div>

  <div class="field">
    <%= form.label :last_name %>
    <%= form.text_field :last_name %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

The /friends/new is calling show for some reason and since the show needs an :id, the call fails with the error. This might be happening die to my recent upgrades of rails and ruby

this is my routes file

RailsRoot::Application.routes.draw do
  resources :friends
  root :to => "accounts#index"

  resources :accounts
end

here is what I see when I run rails routes

                                  Prefix Verb   URI Pattern                                                                                       Controller#Action
                                 friends GET    /friends(.:format)                                                                                friends#index
                                         POST   /friends(.:format)                                                                                friends#create
                              new_friend GET    /friends/new(.:format)                                                                            friends#new
                             edit_friend GET    /friends/:id/edit(.:format)                                                                       friends#edit
                                  friend GET    /friends/:id(.:format)                                                                            friends#show
                                         PATCH  /friends/:id(.:format)                                                                            friends#update
                                         PUT    /friends/:id(.:format)                                                                            friends#update
                                         DELETE /friends/:id(.:format)                                                                            friends#destroy
                                    root GET    /                                                                                                 accounts#index
                                accounts GET    /accounts(.:format)                                                                               accounts#index
                                         POST   /accounts(.:format)                                                                               accounts#create
                             new_account GET    /accounts/new(.:format)                                                                           accounts#new
                            edit_account GET    /accounts/:id/edit(.:format)                                                                      accounts#edit
                                 account GET    /accounts/:id(.:format)                                                                           accounts#show
                                         PATCH  /accounts/:id(.:format)                                                                           accounts#update
                                         PUT    /accounts/:id(.:format)                                                                           accounts#update
                                         DELETE /accounts/:id(.:format)                                                                           accounts#destroy

The problem with the new view is occurring in all of my models and views not just the friends controller (other controller is accounts).

Here is the link to the full stack trace of the error : https://pastecode.io/s/6g8itf96

trying to open my model's new view and expecting an empty form where I can fill in the fields and save . I suspect the /friends/new is calling the show without the :id being the reason of the problem. This was probably not happening before the I upgraded rails to 6.1

1

There are 1 best solutions below

5
Patrick Barattin On

I think the main problem is in the #new method in the controller because you are creating a new friend by saving it in the DB with the .create method. Instead of creating an empty object for the form

Thy to change it to

# GET /friends/new
  def new
    @friend = Friend.new
  end