ETUDESC
ETUDESC

Reputation: 13

Argument Error in *#view for Ruby on Rails

So I have a MVC where I am trying to create a nested resource of todolist and todoitems. In my routes.rb file, I have done

resources :todolists do
   resources :todoitems
end

In my todolists/show.html.erbfile, I have added an Add Todo Item link:

<%= link_to 'Add Todo Item', new_todolist_todoitem_path(@todolist) %> <-- THIS IS THE CAUSE OF THE ERROR

When I looked up the URL of the 'Add Todo Item', the URL gave me http://localhost:3000/todolists/2/todoitems/new, which is correct.

In my rake routes I have this:

todolist_todoitems GET    /todolists/:todolist_id/todoitems(.:format)          todoitems#index
                   POST   /todolists/:todolist_id/todoitems(.:format)          todoitems#create
new_todolist_todoitem GET    /todolists/:todolist_id/todoitems/new(.:format)      todoitems#new
edit_todolist_todoitem GET    /todolists/:todolist_id/todoitems/:id/edit(.:format) todoitems#edit
todolist_todoitem GET    /todolists/:todolist_id/todoitems/:id(.:format)      todoitems#show
                   PATCH  /todolists/:todolist_id/todoitems/:id(.:format)      todoitems#update
                   PUT    /todolists/:todolist_id/todoitems/:id(.:format)      todoitems#update
                   DELETE /todolists/:todolist_id/todoitems/:id(.:format)      todoitems#destroy

And in my todoitems_controller.rb file I have this:

class TodoitemsController < ApplicationController
   before_action :set_todoitem, only: [:show, :edit, :update, :destroy]
   before_action :set_todolist

   # GET /todoitems
   # GET /todoitems.json
   def index
     # @todoitems = Todoitem.all
   end

   # GET /todoitems/1
   # GET /todoitems/1.json
   def show
   end

   # GET /todoitems/new
   def new
     @todoitem = Todoitem.new
   end

   # GET /todoitems/1/edit
   def edit
   end

   # POST /todoitems
   # POST /todoitems.json
   def create
     @todoitem = Todoitem.new(todoitem_params)

     respond_to do |format|
       if @todoitem.save
         format.html { redirect_to @todoitem, notice: 'Todoitem was successfully created.' }
         format.json { render :show, status: :created, location: @todoitem }
       else
         format.html { render :new }
         format.json { render json: @todoitem.errors, status: :unprocessable_entity }
       end
     end
  end

  # PATCH/PUT /todoitems/1
  # PATCH/PUT /todoitems/1.json
  def update
     respond_to do |format|
       if @todoitem.update(todoitem_params)
         format.html { redirect_to @todoitem, notice: 'Todoitem was successfully updated.' }
         format.json { render :show, status: :ok, location: @todoitem }
       else
         format.html { render :edit }
         format.json { render json: @todoitem.errors, status: :unprocessable_entity }
       end
     end
   end

   # DELETE /todoitems/1
   # DELETE /todoitems/1.json
   def destroy
     @todoitem.destroy
     respond_to do |format|
       format.html { redirect_to todoitems_url, notice: 'Todoitem was successfully destroyed.' }
       format.json { head :no_content }
     end
   end

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

     def set_todolist
       @todolist = Todolist.find(params[:todolist_id])
     end

     # Never trust parameters from the scary internet, only allow the white list through.
     def todoitem_params
       params.require(:todoitem).permit(:due_date, :task_title, :description, :done, :todolist_id)
     end
 end

However, when I run the entire code, I get an error saying that in todoitems/_form.html.erb, First argument in form cannot contain nil or be empty.

<%= form_for(@todoitem) do |f| %>  <-- ERROR IS HERE
  <% if @todoitem.errors.any? %>
    <div id="error_explanation">
  <h2><%= pluralize(@todoitem.errors.count, "error") %> prohibited this todoitem from being saved:</h2>

  <ul> 

I have tried to understand why it is not working and I know that this help page is long, but any suggestions in how to fix this will be greatly appreciated!

Upvotes: 0

Views: 150

Answers (1)

jdgray
jdgray

Reputation: 1983

You need to pass your todolist as the first argument since todoitem is nested within todolist:

<%= form_for([@todolist, @todoitem]) do |f| %>

Upvotes: 1

Related Questions