前提・実現したいこと
プログラミング初学者です。
現在、Ruby on Railsで本の投稿ができるアプリケーションを作成しております。
RailsのバージョンはRails 5.2.4で、ログイン機能にはdeviseを利用し、2つのモデルを用意して作成しています。
また、一部、部分テンプレートも使っています。
・ユーザに関するモデル名は、User
Userモデルのカラム名は、
name:名前
introduction:自己紹介文
profile_image_id:「refile」による画像保存用
・投稿データに関するモデル名は、Book
Bookモデルのカラム名は、
title:本のタイトル
body:感想
user_id
実現したいことは、バリデーションチェックが働き、有効でない場合はバリデーションエラーが返るようにすることです。
Userモデルのカラムのバリデーションは
name:一意性を持たせ、かつ2~20文字の範囲で設定
introduction:最大50文字までに設定
Bookモデルのカラムのバリデーションは
title:空でないように設定
body:空でない、かつ最大200文字までに設定
このバリデーション機能を現在はBookモデルのカラムのコードを書いて実装中です。
下記のようなエラーが出てしまい、解決策が分からないため、ご教授いただけると幸いです。
発生している問題・エラーメッセージ
コード NoMethodError in Books#create Showing /home/ec2-user/environment/Bookers2/app/views/users/_user_show.html.erb where line #7 raised: undefined method `name' for nil:NilClass Extracted source (around line #7): 5 <tbody> 6 <tr> 7 <th>name</th><th><%= user.name %></th> 8 </tr> 9 <tr> 10 <th>introduction</th><th><%= user.introduction %></th>
該当のソースコード
ソースコード [ブックモデル] class Book < ApplicationRecord belongs_to :user validates :title, presence: true validates :body, presence: true validates :body, length: { maximum: 200 } end [ユーザーモデル] class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_many :books, dependent: :destroy attachment :profile_image validates :name, uniqueness: true validates :name, length: { in: 2..20 } validates :introduction, length: { maximum: 50 } end [ブックコントローラー] class BooksController < ApplicationController before_action :authenticate_user! before_action :ensure_correct_user, only:[:edit] def new @book = Book.new end def create @book = Book.new(book_params) @book.user_id = current_user.id if @book.save flash[:notice] = "You have created book successfully." redirect_to book_path(@book) else render :index end end def index @books = Book.all @user = current_user @book = Book.new end def show @book = Book.find(params[:id]) @book_new = Book.new end def edit @book = Book.find(params[:id]) end def update @book = Book.find(params[:id]) @book.user_id = current_user.id if @book.update(book_params) flash[:notice] = "You have updated book successfully." redirect_to book_path(@book) else render :edit end end def destroy @book = Book.find(params[:id]) @book.destroy redirect_to books_path end private def book_params params.require(:book).permit(:title, :body) end def ensure_correct_user @book = Book.find(params[:id]) unless @book.user == current_user redirect_to user_path end end end [ユーザーコントローラー] class UsersController < ApplicationController before_action :authenticate_user! before_action :ensure_correct_user, only:[:edit, :show] def show @user = User.find(params[:id]) @book = Book.new @books = @user.books end def new @book = Book.new end def create @book = Book.new(book_params) @book.user_id = current_user.id if @book.save redirect_to book_path(@book) else render :index end end def index @users = User.all end def edit @user = User.find(params[:id]) end def update @user = User.find(params[:id]) @user = current_user if @user.update(user_params) flash[:notice] = "You have updated user succeessfully." redirect_to user_path(@user) else render :edit end end private def user_params params.require(:user).permit(:name, :introduction, :profile_image_id) end def ensure_correct_user @user = User.find(params[:id]) unless @user == current_user redirect_to user_path(current_user.id) end end end [部分テンプレート、_book_new.html] <h2>New book</h2> <%= form_with model: book, local:true do |f| %> <div class="form-group"> <%= f.label :title, 'Title' %> <%= f.text_field :title, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :body, 'Opinion' %> <%= f.text_area :body, class: 'form-control' %> </div> <div><%= f.submit 'Create Book', class: 'btn btn-success' %></div> <% end %> [部分テンプレート、_user_show.html] <h2>User info</h2> <%= attachment_image_tag user, :profile_image, size: "60x60", farmat: 'jpg', fallback: "no_image.jpg" %> <table class="table"> <tbody> <tr> <th>name</th><th><%= user.name %></th> </tr> <tr> <th>introduction</th><th><%= user.introduction %></th> </tr> </tbody> </table> <div class="row"> <%= link_to edit_user_path(user), class: "btn btn-outline-dark btn-block" do %> <span class="fas fa-user-cog"></span> <% end %> </div> [books/index.html(投稿に失敗した時は本の一覧画面に返るようにしたいので、ここに<% if @book.errors.any? %>を書きました)] <div class="container"> <div class="row"> <% if @book.errors.any? %> <%= @book.errors.count %>error prohibited this book from being saved:<br> <% @book.errors.full_messages.each do |message| %> <%= message %> <% end %> <% end %> <div class="col-md-3"> <%= render 'users/user_show', user: @user %> <%= render 'books/book_new', book: @book %> </div> <div class="col-md-8 offset-md-1 pt-3"> <%= render 'books/book_index', books: @books %> </div> </div>
試したこと
コントローラなど見返したのですが、どのように直せば良いか分からなかったです。
1:Nの関係なども復習下のですがはっきりできませんでした。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
ご指摘ありがとうございます。
コピペして訂正しました、
初めての質問で見辛い点もあるかと思いますが、よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー