Search code examples
ruby-on-railsrubypartials

NoMethodError in Users#show (Ruby Rails)


I'm running into a NoMethodError in my Users#show when trying to include a form partial for submitting a task item (_form.html.erb). My other partial (_item.html.erb) is rendering properly. My item model and my user model are related to each other, user has_many :items, and item belongs_to :user.

Any and all help would be greatly appreciated!

Below is my routes.rb

Rails.application.routes.draw do
  get 'welcome/index'

  get 'welcome/about'

  root 'users#show'

  resources :users do
    resources :items, only: [:new, :create]
  end


  devise_for :users
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

Below is my terminal output

ActionView::Template::Error (undefined method `items_path' for #<#<Class:0x007fefeca61dd0>:0x007fefeca58b18>
Did you mean?  items_create_path):
    1: <h4> Create a new to-do item </h4>
    2: 
    3: <%= form_for @item do |f| %>
    4:   <%= f.label :name %>
    5:   <%= f.text_field :name, class: 'form-control', placeholder: "Enter task here" %>

Items Controller

class ItemsController < ApplicationController

    def new
        @item = Item.new
    end

    def create
        @item = Item.new
        @item.user = current_user
        @item.name = params[:item][:name]

        if @item.save
            flash[:notice] = "Item saved"
            redirect_to @item
        else
            flash.now[:alert] = "Item was not created, please try again."
            render :new
        end
    end
end

Users Controller

class UsersController < ApplicationController


  def show
    if !current_user.nil?
      @user = current_user
      @item = Item.new
      @items = @user.items
    else
      redirect_to new_user_registration_path
    end  
  end
end

Users#show page

<h2> Your to-do list</h2>


  <div class="col-md-8">
    <div class='items'>
      <%= render partial: "items/item", local: { item: @item} %>
    </div>
  </div>
  <div class="col-md-8">
    <div class='new-item'>
      <%= render partial: "items/form", local: { item: @item } %>
    </div>
  </div>

Solution

  • In your routes.rb file, you have items defined as a nested resource. You can check all of your routes by running this command on your terminal: rake routes.

    For your routes specifically, you say:

    resources :users do
      resources :items, only: [:new, :create]
    end
    

    This would give you routes for GET /users/:user_id/items/new and POST /users/:user_id/items. However, in your form, it looks like you're trying to do this: <%= form_for @item do |f| %>. You don't have a route defined for an item by itself. You'll need to supply a user as well.

    Try this for your form:

    <%= form_for [@user, @item] do |f| %>
    

    And something like this in your ItemsController:

    class ItemsController
      def new
        @user = current_user
        @item = Item.new
      end
    end