前提・実現したいこと
初質問なのでつたないところがありましたら、すみません。
Rubyonrailsで、おすすめの本を投稿するサイトを作っています。
本の投稿にタグを付けられる機能を実装しようと考えています。
タグの保存まではできました。
タグを検索した後、検索結果を表示しようとしたところエラーメッセージがでました。
なぜ、<% @tags.books.each do |tag| %>で紐づけしている投稿が表示できないのか、ご指導よろしくお願いします。
ruby '2.6.3'
gem 'rails', '~> 5.2.5'
発生している問題・エラーメッセージ
NoMethodError in Searchs#search Showing /home/ec2-user/environment/bookers8d/app/views/searchs/search.html.erb where line #23 raised: undefined method `books' for #<Tag::ActiveRecord_Relation:0x00007f6f012be0b8> Extracted source (around line #23): </thead> <tbody> <% @tags.books.each do |tag| %> #エラーが出ている部分 <tr> <td> </td>
該当のソースコード
Rails.application.routes.draw do devise_for :users # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html get 'search' => 'searchs#search' end
class Book < ApplicationRecord has_many :tag_maps, dependent: :destroy has_many :tags, through: :tag_maps def save_tag(sent_tags) current_tags = self.tags.pluck(:tag_name) unless self.tags.nil? old_tags = current_tags - sent_tags new_tags = sent_tags - current_tags old_tags.each do |old| self.tags.delete Tag.find_by(tag_name: old) end new_tags.each do |new| new_book_tag = Tag.find_or_create_by(tag_name: new) self.tags << new_book_tag end end end
class Tag < ApplicationRecord has_many :tag_maps, dependent: :destroy, foreign_key: 'tag_id' has_many :books, through: :tag_maps def self.search(keyword) @tags = Tag.where("tag_name LIKE?","%#{keyword}%") end end
class TagMap < ApplicationRecord belongs_to :book belongs_to :tag validates :book_id,presence:true validates :tag_id,presence:true end
class BooksController < ApplicationController before_action :authenticate_user! before_action :ensure_correct_user, only: [:edit, :update, :destroy] def index if params[:button].to_i == 1 @books = Book.all.order(id: "ASC") elsif params[:button].to_i == 2 @books = Book.all.order(rate: "DESC") else @books = Book.all end @book = Book.new end def create @book = Book.new(book_params) tag_list = params[:book][:tag_name].split(nil) @book.user_id = current_user.id if @book.save @book.save_tag(tag_list) redirect_to book_path(@book), notice: "You have created book successfully." else @books = Book.all render 'index' end end private def book_params params.require(:book).permit(:title, :body, :rate) end def ensure_correct_user @book = Book.find(params[:id]) unless @book.user == current_user end end end
class SearchsController < ApplicationController def search keyword = params[:keyword] @tags = Tag.search(keyword) @book = Book.new end end
<li> <%= form_with(url: search_path, local: true, method: :get) do |form| %> <%= form.text_field :keyword %> <%= form.submit "検索", class: "btn btn-primary" %> <% end %> </li>
<div class='container px-5 px-sm-0'> <%= render 'layouts/errors', obj: @book %> <div class='row'> <div class='col-md-3'> <h2>User info</h2> <%= render 'users/info', user: current_user %> <h2 class="mt-3">New book</h2> <%= render 'books/form', book: @book %> </div> <div class='col-md-8 offset-md-1'> <h2>Books</h2> <table class='table table-hover table-inverse'> <thead> <tr> <th></th> <th>Title</th> <th>Opinion</th> <th>Category</th> <th colspan="2"></th> </tr> </thead> <tbody> <% @tags.books.each do |tag| %> #エラー該当 <tr> <td> </td> <td></td> <td></td> <td></td> </tr> <% end %> </tbody> </table> </div> </div> </div>
試したこと
他の質問の回答を見て、<%= tag.books.map(&:title).join(', ') %>を試したところ、titleは表示ができました。表示できた理由は理解していません。
投稿した本人のimageを表示したいとき、
<%= attachment_image_tag(@tags.book.map(&:user), :profile_image, :fill, 50, 50, fallback: "no-image-icon.jpg") %>で表示できませんでした。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。