我正在运行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 %>
答案 0 :(得分:3)
current_user
行动中的{p> nil
为new
。而且您无法在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