AHmed
AHmed

Reputation: 381

UrlGenerationError Missing Required Key [:id] Error?

When I want to create an article I get this error after clicking on the create article button

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

although I make sure there is a user who is logged in before creating the article. Here's my code:

articles_controller.rb

class ArticlesController < ApplicationController
  before_action :require_user , except:[:index,:show]

  def index
      @articles = Article.all
  end  

  def new
    @article = Article.new
  end

  def create
    @article = Article.new(article_params)
    if @article.save
        flash[:notice] = "Your Article was Created"
    else
        render 'new'
    end
    redirect_to article_path(@article)
  end

  def show
    @article = Article.find(params[:id])
  end

  def edit
    @article = Article.find(params[:id])
  end

  def update
    @article = Article.find(params[:id])
    if @article.update(article_params)
        flash[:notice] = "Your Article was Updated"
        redirect_to article_path(@article)
    else
        render 'edit'
    end
  end

  def destroy
    @article = Article.find(params[:id])
    @article.destroy
    flash[:notice] = "Your Article was deleted"
    redirect_to articles_path(@article)
  end

  private

  def article_params
    params.require(:article).permit(:title,:description)
  end

end

users_controller.rb

class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = "You Signed up successfully"
      redirect_to articles_path
    else
      render 'new'
    end
  end

  def show
    @user = User.find(params[:id])
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
      flash[:success]= "Your user was updated"
      redirect_to articles_path
    else
      render 'edit'
    end
  end

  private

  def user_params
    params.require(:user).permit(:username,:email,:password)
  end

end

views/new.html

    <h1>New Article</h1>
<%= form_for @article do |f| %>

<p>title<%= f.text_field :title %></p><br>
<p>description<%= f.text_area :description %></p>
<%= f.submit "Create" %>
<%end%>

here's my github repo

Upvotes: 1

Views: 1575

Answers (2)

mrvncaragay
mrvncaragay

Reputation: 1260

When you create an invalid article it will give you the missing required keys: [:id] since it fails to @article.save it will redirect_to article_path(@article) in which in this case @article.id is nil

def create
    @article = Article.new(article_params)
    if @article.save
        flash[:notice] = "Your Article was Created"
    else
        render 'new'
    end
    redirect_to article_path(@article)
end

Just move redirect_to article_path(@article) if @article.save is true.

def create
   @article = Article.new(article_params)
   if @article.save
       flash[:notice] = "Your Article was Created"
       redirect_to article_path(@article)
    else
       render 'new'
    end       
end

Edit:

I cloned your repo and the problem exists when creating the article without user_id. added the changes in the bottom and it seem to be working as expected.

def create
       @article = current_user.articles.build(article_params)

       if @article.save
           flash[:notice] = "Your Article was Created"
           redirect_to article_path(@article)
        else
           render 'new'
        end       
    end

Hope that helps!

Upvotes: 2

Govind shaw
Govind shaw

Reputation: 427

You got this error because of render and redirect both getting executed when @article.save fails.So it goes to else part where it get render to new and again redirects to show page with id = nil.

def create
   @article = Article.new(article_params)
   if @article.save
       flash[:notice] = "Your Article was Created"
       redirect_to article_path(@article.id) # or @article
    else
       render 'new'
    end       
end 

Upvotes: 1

Related Questions