Rails 4: Receiving the following error: First argument in form cannot contain nil or be empty

混江龙づ霸主 提交于 2019-12-11 06:41:52

问题


I am receiving the following error on a project of mine: First argument in form cannot contain nil or be empty. I am trying to create an edit page for my code. Fairly new with Rails and trying to learn without scaffolding.

Controller:

class BooksController < ApplicationController
def new
  @book = Book.new 
  @authors = Author.all
end

def edit 
  @book = Book.find(params[:id])  
end 

def show
 #Notice how the @books is plural here. 
 @books = Book.all
 @authors = Author.all
 #@books = Book.where(id: params[:id])
end 

#Create method will save new entries 
def create 
 @book = Book.new(book_params)
 @authors = Author.all

 if @book.save
    flash[:success] = "Book Added to Databse!"
    redirect_to @book  
  else
    render 'new'
  end 
 end 

 private 

 #Note that this method will go up into the create method above. 

 def book_params 
  params.require(:book).permit(:title, :pub_date, :publisher, :author_id)
 end 
end

Model Page: (For Book)

class Book < ActiveRecord::Base
  validates :title, :pub_date, :publisher, presence: true
  validates :title, uniqueness: true 
  belongs_to :author 
end

Model Page: (For Author)

class Author < ActiveRecord::Base
  validates :name, presence: true
  validates :name, uniqueness: true 
  has_many :books 
end

Edit page:

<h1>Update a book entry</h2>

<div class="row">
 <div class="col-md-6 col-md-offset-3">

   <%= form_for(@book) do |f| %> **ERROR SEEMS TO BE RIGHT HERE!!!**
     <%= render 'form' %>

     <div class="form-group">
      <%= f.label :title %>
      <%= f.text_field :title, class: 'form-control' %>
     </div>

    <div class="form-group">
      <%= f.label :pub_date %>
      <%= f.text_field :pub_date, class: 'form-control' %>
    </div>

    <div class="form-group">
    <%= f.label :publisher %>
    <%= f.text_field :publisher, class: 'form-control' %><br />
  </div>

  <div class="form-group">
    <%= f.select(:author_id, 
    @authors.collect {|a| [ a.name, a.id ]},              
    {:include_blank => 'Please select an author'}, 
    class: "form-control") %><br />
  </div>

   <%= f.submit 'Save Changes', class: "btn btn-primary" %> 

  <% end %>
 </div>
</div>

Render form page (_form.html.erb)

  <% if @book.errors.any? %>
   <div id="error_explanation">
    <div class="alert alert-danger">
     <h2><%= pluralize(@book.errors.count, "error") %> 
   prohibited this entry       from being saved:</h2>
   <ul>
   <% @book.errors.full_messages.each do |msg| %>
    <li><%= msg %></li>
  <% end %>
  </ul>
  </div>


  </div>
 <% end %>

SHOW PAGE:

    <div class="move">
   <h1>Showing Book Titles:</h1>
  </div><br />

 <div class="row">
  <% @books.each do |book| %>
  <div class="col-md-4">
    <div class="panel panel-default">
        <div class="panel-body">
            <h2><%= book.title %></h2> 
            <h2><%= book.publisher %></h2>
            <h2><%= book.pub_date %></h2>
            <h2><%= book.author.name %></h2>
            <h2><%= link_to "Edit", edit_path, class: "btn btn-primary" %>
        </div>
    </div>
</div>
<% end %>

Here is my Log telling me what is wrong:

Started GET "/edit" for ::1 at 2015-08-14 16:49:17 -0400
Processing by BooksController#edit as HTML
  Rendered books/edit.html.erb within layouts/application (2.2ms)
Completed 500 Internal Server Error in 9ms (ActiveRecord: 0.0ms)

ActionView::Template::Error (First argument in form cannot contain nil or be empty):
    3: <div class="row">
    4:   <div class="col-md-6 col-md-offset-3">
    5: 
    6:     <%= form_for(@book) do |f| %>
    7:       <%= render 'form' %>
    8: 
    9:       <div class="form-group">
  app/views/books/edit.html.erb:6:in `_app_views_books_edit_html_erb___525891009649529081_70260522100960'

I will say that I have deleted the first 14 books from my data base and so the first book start on ID 14. Not sure if that matters.

Finally, I have tried adding all of these different instance variables to my controller in the edit method:

   #@book = Book.where(id: params[:id])
   #@book = Book.find_by_id(params[:id])
   #@book = Book.all 
   #@book = Book.find_by_id(params[:id])
   #book = Book.new(book_params)

   #When I use the two below lines, 
  there are no error pages but create a new   entry. 
  #@book = Book.new 
  #@authors = Author.all

Any Help will be appreciated! Thank you for your time!!!


回答1:


This error means that the first argument to form_for is a nil value (in this case @book). Most of the times I've seen this, it's due to malformed controller actions, but that doesn't look to be the case here. From what I can tell, it's one of two things:

  1. You're trying to edit a Book that doesn't exist. Do a .nil? check on it before deciding to render the form, and render an error message (or redirect) instead.

  2. Your routes are broken, and the edit action is not rendering the edit view. This is most likely not the case.

EDIT:

After updating with your template for show, this looks like your problem:

<%= link_to "Edit", edit_path, class: "btn btn-primary" %>

I see two problems with this (though I'll need to see the output of rake routes to verify). Firstly, you need to pass an argument to the edit path (without them, where would your params come from?). Secondly, the default route for this would be edit_book_path.

Try this:

<%= link_to "Edit", edit_book_path(book), class: "btn btn-primary" %>




回答2:


Assuming book ID 14 is in your database, you should be able to navigate to localhost:3000/books/14/edit if you created it with something like resources :books (documentation here). If this doesn't work, either your routes are not defined correctly or book with ID 14 does not exist in your database.

On your show view, change the link_to line to:

<%= link_to 'Edit', edit_book_path(book), class: "btn btn-primary" %>

So two changes:

  1. Again, assuming book is a Restful resource, when you run rake_routes, you should see the path to edit is edit_book_path.
  2. You need to pass the book instance with the path so Rails knows which object you wish to edit.

I found the correct syntax here.

Hope this helps.



来源:https://stackoverflow.com/questions/32018830/rails-4-receiving-the-following-error-first-argument-in-form-cannot-contain-ni

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!