Home > front end >  No route matches missing required keys: [:id]. destroy
No route matches missing required keys: [:id]. destroy

Time:09-27

resources :users do
   resources :posts, only: %i[create destroy]
end  
class PostsController < ApplicationController
  before_action :set_user
  before_action :set_post, expect: [:create]
  def create
    @post = @user.posts.build(params_post)

    if @post.save
      flash[:success] = "Post created!"
      redirect_to user_path(@user)
    else
      @posts = Post.all
      render "users/show"
    end 
  end 

  def destroy
    @post.destroy
    flash[:success] = "Post deleted!"
    redirect_to user_path(@user)
  end 

  private

  def set_user
    @user = User.find(params[:user_id])
  end 

  def set_post
    @post = @user.posts.find(params[:id])
  end 

  def params_post
    params.require(:post).permit(:content)
  end 
end
# views/users/show.html.erb 
<article>
  <% @user.posts.each do |post| %>
    <p> 
      <%= post.content %>
      <small><%= formatted_at_time(post.created_at) %></small>
    </p>

    <% if post.user == current_user %>
    <%= link_to "Delete", user_post_path(@user, post),
        data: { method: :delete, confirm: "Are you sure?" }, class: "btn btn-danger" %>
    <% end %>
  <% end %>
</article>

ActionView::Template::Error (No route matches {:action=>"destroy", :controller=>"posts", :id=>nil, :user_id=>"4"}, missing required keys: [:id]): 19:

20: 21: <% if post.user == current_user %> 22: <%= link_to "Delete", user_post_path(@user, post), 23: data: { method: :delete, confirm: "Are you sure?" }, class: "btn btn-danger" %> 24: <% end %> 25: <% end %>

Thank you in advance!

CodePudding user response:

You must have initialized a new post on users#show show action in users controller, this lead to a new post that belongs to the user, so when you loop it in the show template the post also in the loop, but that new post is a new record and has no id.

Since you're looping @user.posts, there's no need to check post.user == current_user and please change it from this:

<% if post.user == current_user %>
    <%= link_to "Delete", user_post_path(@user, post),
        data: { method: :delete, confirm: "Are you sure?" }, class: "btn btn-danger" %>
<% end %>

to this

<% if post.persisted? %>
    <%= link_to "Delete", user_post_path(@user, post),
        data: { method: :delete, confirm: "Are you sure?" }, class: "btn btn-danger" %>
<% end %>

#persisted?

Returns true if the record is persisted, i.e. it’s not a new record and it was not destroyed, otherwise returns false.

Check more about #persisted? here https://apidock.com/rails/v5.2.3/ActiveRecord/Persistence/persisted?

  • Related