NoMethodError nil的未定义方法:NilClass

时间:2016-09-11 20:53:33

标签: ruby-on-rails twitter-bootstrap

我正在运行Windows 10.我刚刚做了一个

rails generate migration add_user_id_to_books user_id:integer
rake db:migrate

我想从当前用户创建一本书。但是当我去"添加书"在导航栏上我收到此消息:

NoMethodError in BooksController#new undefined method `books' for nil:NilClass

提取的来源(第12行): 10 11 12 13 14 15

def new
  @book = current_user.books.build
end

book.rb

class Book < ApplicationRecord
  belongs_to :user
end

user.rb

class User < ApplicationRecord
  has_many :books

devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable
end

books_controller.rb

 class BooksController < ApplicationController
   before_action :find_book, only: [:show, :edit, :update, :destroy]

   def index
    @books = Book.all.order("created_at DESC")
   end

  def show
  end   

  def new
    @book = current_user.books.build
  end

  def create
    @book = current_user.books.build(book_params)

    if @book.save
      redirect_to root_path
    else
      render 'new'
    end     
  end

  def edit
  end

  def update
    if @book.update(book_params)
      redirect_to book_path(@book)
    else
      render 'edit'
    end     
  end

  def destroy
    @book.destroy
    redirect_to root_path
  end   

  private

  def book_params
    params.require(:book).permit(:title, :description, :author)
  end

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

的routes.rb

Rails.application.routes.draw do
devise_for :users
resources :books
root 'books#index'
end

application.html.erb

  <!DOCTYPE html>
  <html>
  <head>
 <title>BookReview</title>
 <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-        track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>

  

<nav class="navbar navbar-default">
    <div class="container">
      <div class="navbar-header">
        <%= link_to "Book Review", root_path, class: "navbar-brand" %>
      </div>
      <ul class="nav navbar-nav">
        <li><%= link_to "Sign Up", new_user_registration_path %></li>
        <% if user_signed_in? %>
          <li><%= link_to "Sign Out", destroy_user_session_path, method: :delete %><li>
        <% else %>
          <li><%= link_to "Log In", new_user_session_path %></li>   

        <% end %>
      </ul>

      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Add Book", new_book_path %></li>
        <% if user_signed_in? %>
        <% end %>           
      </ul> 


    </div>

</nav>  

<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

<%= yield %>

1 个答案:

答案 0 :(得分:3)

current_user行动中的{p> nilnew。而且您无法在books对象上调用nil方法。

向控制器添加before_filter以确保current_user不是nil(即用户已登录)。

class BooksController < ApplicationController
  before_action :authenticate_user!
  # rest of the code
end

authenticate_user!devise gem提供的辅助方法。当用户未登录时,authenticate_user!方法会将用户重定向到登录页面。

有关详情,请参阅https://github.com/plataformatec/devise#controller-filters-and-helpers