@harahide1212

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

railsにて作成したサイトにコメント機能実装中のエラーについて

Q&A

Closed

解決したいこと

railsにてログイン、ログアウト、本の投稿、いいね、コメントの機能を持つサイトの作成をしています。
そのコメント機能の実装中に発生したエラーについて質問させていただきます。

すでに投稿してあるコメントをユーザーのプロフィール画像の横に表示させたいです。

発生している問題・エラー

NameError in Books#show
undefined local variable or method `book' for #<#<Class:0x00007f07246c50c0>:0x00007f0724508d40>
Did you mean?  @book @books

該当するソースコード

show.html.erb
<%= render 'users/list', user: @user ,book: @booknew %>

      <div class="col-xs-9">
        <h2>Book detail</h2>
          <table class="table table-hover table-inverse">
            <thead>
              <tr> 
                <th>Book detail</th>
                <th></th>
                <th></th>
                <th colspan="3"></th>
              </tr>
            </thead>

            <tbody>
                <tr> 
                  <td>
                    <%= link_to user_path(@user.id) do %>
                      <%= attachment_image_tag @user, :profile_image, :fill, 60, 60, format:'jpeg', class: "#", fallback: "no_image.jpg", size:'60x60' %>
                      <%= @user.name%>
                    <% end %>
                  </td>
                  <td>
                    <%= link_to @book.title, book_path(@book) %>
                  </td>
                  <td>
                    <%= @book.body %>
                  </td>
                                  <td>
                    <% if @book.favorited_by(current_user) %>
                      <%= link_to  "", "favorites/#{@book.id}/destroy", method: :delete, class: "glyphicon glyphicon-heart" %>
                      <%= @book.favorites.count %>
                      <% else %>
                      <%= link_to "", "favorites/#{@book.id}/create", method: :post, class: "glyphicon glyphicon-heart" %>
                      <%= @book.favorites.count %>
                    <% end %>
                  </td>
                </tr>
                <tr>
                  <td>
                    <%= attachment_image_tag @user, :profile_image, :fill, 60, 60, format:'jpeg', class: "#", fallback: "no_image.jpg", size:'60x60' %>
                    <%= @book.comment %>
                  </td>
                  <td class="btn btn-danger" style="margin-top: 10px;">
                    <%= link_to 'Destroy', book_path(@book.id), method: :delete, "data-confirm" => "本当に消しますか?" %>
                  </td>
                </tr>
            </tbody>
          </table>

          <%= form_for [@book, @comment] do |f| %>
            <%= f.text_area :comment %>
            <%= f.submit 'コメントする' %>
          <% end %>

      </div>

上記コードの<%= attachment_image_tag @user, :profile_image, :fill, 60, 60, format:'jpeg', class: "#", fallback: "no_image.jpg", size:'60x60' %>
この真横にコメントを表示させたいです。
そして、エラーが発生しているのは、<%= @book.comment %>この記述になります。

books_comments_controller.rb
def create
    @book = Book.find(params[:book_id])
    @comment = @book.book_comments.new(book_comment_params)
    @comment.user_id = current_user.id
    @comment.save
    redirect_to book_path(@book)
  end

  def destroy
  end

  private
  def book_comment_params
    params.require(:book_comment).permit(:comment)  #formにてpost_idパラメータを送信して、コメントへpost_idを格納するようにする必要がある。
  end
end
books_controller.rb
def index
    @books = Book.all
    @book = Book.new
    @user = current_user
    # @favorite_count = Book.where(book_id: "@book.id")
  end

  def show
    @book = Book.find(params[:id]) 
    @books = Book.all
    @user = @book.user
    @booknew = Book.new
    @comment = BookComment.new
  end

  def new
    @book = Book.new
  end

  # 1:N 
      # 相手のモデル名_id = 相手のインスタンス.id
  def create
    @book = Book.new(book_params)
    @book.user_id = current_user.id
    @books = Book.all
    if @book.save
       flash[:notice] = "Book was successfully created."
       redirect_to book_path(@book.id)
    else
       @books = Book.all
       @user = current_user
       render action: :index
    end
  end

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

  def update
    @book = Book.find(params[:id])
    if @book.update(book_params)
       flash[:notice] = "Book was successfully updated."
       redirect_to book_path(@book)
    else
       render action: :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 check_current_user_book
    @book = Book.find(params[:id])
    if current_user.id != @book.user.id
      redirect_to books_path
    end
  end
end

以下アソシエーションの記述になります。

book.rb
class Book < ApplicationRecord
    validates:title, presence: true
    validates:body, presence: true

    validates:body, length: { maximum: 200 }

    belongs_to :user
    has_many :favorites
    has_many :book_comments
    def favorited_by(user)
        favorites.where(user_id: user.id).exists?
    end
end
book_comment.rb
class BookComment < ApplicationRecord
  belongs_to :user
  belongs_to :book
end
favorite.rb
class Favorite < ApplicationRecord
    belongs_to :book
    belongs_to :user
end

下記にテーブルの内容を記載します。

schema.rb
create_table "book_comments", force: :cascade do |t|
    t.string "comment_content"
    t.integer "user_id"
    t.integer "book_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "comment"
    t.index ["book_id"], name: "index_book_comments_on_book_id"
    t.index ["user_id"], name: "index_book_comments_on_user_id"
  end

  create_table "books", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "title"
    t.text "body"
    t.string "user_id"
  end

  create_table "favorites", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "user_id"
    t.integer "book_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.text "introduction"
    t.string "profile_image_id"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

end

自分で試したこと

エラー文「Did you mean? @book @books」にある通り、@book @booksに修正し試しました
結果は、「method book'」が「methodcomment'」に変わり解決できませんでした。

よろしくお願いいたします。

0 likes

2Answer

アソシエーション(bookとcomment)や、それぞれのテーブルの情報があると回答する側も分かりやすいなと思いました。どのような設計になっているのか、予想はつきますが、あくまで予想の範囲を出ないので。
あとは、エラーがundefinedということですので、もしデバッグをされていないのであれば、binding.pryなどでデバッグしてみることをおすすめします。デバッグして、変数の値をチェックしてみるとかすると、割と簡単に解決できるかもしれません。
binding.pryの使い方についてはご自分で調べてみてください。
今回がいい機会だと思って、pryの使い方を覚えてみてはいかがでしょう。

参考までに
https://qiita.com/STHEXA/items/1de2411cb3987066c9b9

1Like
NameError in Books#show
undefined local variable or method `book' for #<#<Class:0x00007f07246c50c0>:0x00007f0724508d40>
Did you mean?  @book @books

こちらのエラーですが,読み解くと以下になります.

  • Books#showを取り扱っている際に,NameError が発生した.
    • book という名前でメソッドかローカル変数が未定義です.(book が見つからなかった)
      • @book, @books ではありませんか?

今貼られている show.html.erbbooks_controller.rb(の show メソッド) では book という名前を使ってないので,どこにその記述があるかわからないですが,
エラーになった時点では,その記述がどこか(render 側の可能性もある) にあったと推測します.

上記コードの<%= attachment_image_tag @user, :profile_image, :fill, 60, 60, format:'jpeg', class: "#", fallback: "no_image.jpg", size:'60x60' %>
この真横にコメントを表示させたいです。

こちらですが,table を使っているので td を使ってもよいかもしれません.

                  <td>
                    <%= attachment_image_tag @user, :profile_image, :fill, 60, 60, format:'jpeg', class: "#", fallback: "no_image.jpg", size:'60x60' %>
+                  </td>
+                  <td>
                    <%= @book.comment %>
                  </td>
0Like

Your answer might help someone💌