前提・実現したいこと
現在Railsを使用してYouTubeの動画をタイトルとURLの末尾11桁を利用して記録するWebアプリを作り、
タグ機能を実装することで登録した動画をジャンルや単語でまとめることで擬似的にYouTubeのプレイリストを作成出来るようなアプリを作ろうとしています。
そこでgem kaminari
を使用してのページネーションを実現しようとしていたのですが、
プルダウン式のタグ選択機能と併用しようとしていたら上記タイトル通りのエラーが発生してしまいました。
現状の自分の知識では該当するエラーを解決出来ず、検索しても自分の環境に該当するものや近い解決手段が見付からずどうしても直接解決に至りそうなものが見つからなかったので質問させていただきました。
未定義であると言われているtotal_pages
という単語についても自分でController
やModel
に記述した記憶も無く心辺りが無くておそらくgem側が用意しているものなのでは無いかと思うのですが、
コードを書き換えて色々と試してみてもエラーの内容が全く変わらず途方に暮れているところです。
また、念の為、タグによる検索機能を排除した状態で通常通りのページネーションは可能なのかと思いindex.html.erb
のタグのプルダウン
を行うための該当コードをコメントアウトしてみたところページネーションは問題無く動作しました。
おそらくmovieとplaylistを繋いでいることがページネーションに引数を渡して結果を表示させる際に干渉しているのではないかと考えました。
エラーメッセージ内に記載されているActiveRecord_Relation
がなんとなくリレーションに関わるものであることは分かったのですが、該当するファイルがあるvendor以下のファイルについてはあまり触ったことが無く全く理解が出来ていない状態なのでどうして良いか分からない状態です。
予想ではmovies_controller.rb
内のindexアクションの記述によって改善出来るのでは無いかと考えているのですが、どのように記述を変えるべきなのか見当が付いていない状況です。
勉強不足・力不足で自力ではまだまだ足りないところが多く皆様のお力添えを頂きたいと思い質問させていただきました。
どなたかご協力いただければ幸いです。宜しくお願いしたします。
発生している問題・エラーメッセージ
NoMethodError in Movies#index undefined method `total_pages' for #<Movie::ActiveRecord_Relation:0x00007fde8d966888>
該当のソースコード
Modelはuser,playlist,movieそしてmovieとplaylistの間を繋いでリレーションを作っている中間テーブルのmovie_playlist_relationがあります。
Ruby
1# app/models/user.rb ユーザーのモデル 2 3class User < ApplicationRecord 4 devise :database_authenticatable, :registerable, 5 :recoverable, :rememberable, :validatable 6 has_many :movies, dependent: :destroy 7 has_many :playlists, dependent: :destroy 8end
Ruby
1# app/models/playlist.rb プレイリストのデータを記録するためのモデル 2 3class Playlist < ApplicationRecord 4 has_many :movie_playlist_relations, dependent: :destroy 5 has_many :movies, through: :movie_playlist_relations 6 default_scope -> { order(created_at: :desc) } 7end
Ruby:
1# app/models/movie.rb 動画を登録しタイトルとURLを記録するためのモデル 2 3class Movie < ApplicationRecord 4 has_many :movie_playlist_relations, dependent: :destroy 5 has_many :playlists, through: :movie_playlist_relations 6 default_scope -> { order(created_at: :desc) } 7end
Ruby
1# app/models/movie_playlist_relation.rb 中間テーブルのモデル 2 3class MoviePlaylistRelation < ApplicationRecord 4 belongs_to :movie 5 belongs_to :playlist 6end
Ruby
1# app/controllers/movies_controller.rb 動画を記録し記録した動画の一覧などを表示したりするためのController 2 3class MoviesController < ApplicationController 4 before_action :set_movie, only: [:show, :edit, :update, :destroy] 5 # before_action :authenticate_user! 6 7 def index 8 # この箇所をどうにかしたいと思っているが解決策が分からない。 9 @movies = Movie.page(params[:page]) 10 @movies = params[:playlist_id].present? ? Playlist.find(params[:playlist_id]).movies : Movie.all.page(params[:page]) 11 end 12 13 def show 14 @movie = Movie.find(params[:id]) 15 end 16 17 def new 18 @movie = Movie.new 19 @movie.movie_playlist_relations.build 20 end 21 22 def edit 23 end 24 25 def create 26 @movie = current_user.movies.build(movie_params) 27 url = params[:movie][:youtube_url] 28 url = url.last(11) 29 @movie.youtube_url = url 30 31 respond_to do |format| 32 if @movie.save 33 format.html { redirect_to @movie, notice: 'Movie was successfully created.' } 34 format.json { render :show, status: :created, location: @movie } 35 else 36 format.html { render :new } 37 format.json { render json: @movie.errors, status: :unprocessable_entity } 38 end 39 end 40 end 41 42 def update 43 respond_to do |format| 44 if @movie.update(movie_params) 45 format.html { redirect_to @movie, notice: 'Movie was successfully updated.' } 46 format.json { render :show, status: :ok, 47 location: @movie } 48 else 49 format.html { render :edt } 50 format.json { render json: @movie.errors, status: 51 :unprocessable_entity } 52 end 53 end 54 end 55 56 def destroy 57 @movie.destroy 58 respond_to do |format| 59 format.html { redirect_to movies_url, notice: 'Movie was successfully destroyed.' } 60 format.json { head :no_content } 61 end 62 end 63 64 private 65 66 def set_movie 67 @movie = Movie.find(params[:id]) 68 end 69 70 # def movie_params 71 # params.require(:movie).permit(:title, :youtube_url) 72 # params.require(:playlist).permit(:playlist_name, playlist_ids:[]) 73 # end 74 75 def movie_params 76 params.require(:movie).permit(:title, :youtube_url, :playlist_name, playlist_ids: []) 77 end 78end
Ruby
1# routes.rb deiviseを使用しているためuser周りのルーティングがややごちゃごちゃしてしまっているかもしれません 2 3Rails.application.routes.draw do 4 root 'static_pages#home' 5 get 'help', to:'static_pages#help' 6 get 'about', to:'static_pages#about' 7 get 'contact', to:'static_pages#contact' 8 get '/', to: 'users#index' 9 devise_for :users, :controllers => { 10 :registrations => 'users/registrations', 11 :sessions => 'users/sessions', 12 :passwords => 'users/passwords' 13 } 14 devise_scope :user do 15 # get 'user/:id', to: 'users/registrations' 16 get 'signup', to: 'users/registrations#new' 17 get 'login', to: 'devise/sessions#new' 18 post 'login', to: 'devise/sessions#create' 19 delete 'signout', to: 'devise/sessions#destroy' 20 end 21 resources :users, :only => [:index, :show] 22 resources :movies do 23 resource :playlists, only: [:create, :destroy] 24 end 25 resources :playlists 26end
ERB
1# app/views/movies/index.html.erb 2 3<p id="notice"><%= notice %></p> 4 5<h1>Movies</h1> 6 7 # ここからがタグのプルダウンをするためのコード 8 <%= form_tag movies_path, method: :get, class: 'boards__searchForm' do %> 9 <%= select_tag :playlist_id, 10 options_from_collection_for_select(Playlist.all, :id, :playlist_name, params[:playlist_id]), 11 { 12 prompt: 'プレイリストをタグで絞り込み検索', 13 onchange: 'submit(this.form);' 14 } 15 %> 16 <% end %> 17 #ここまでがタグのプルダウンをするためのコード 18 19<%= paginate @movies %> 20 21<div class="container-fluid"> 22 <div class="row"> 23 <% @movies.each do |movie| %> 24 <div class="col-md-6"> 25 <div> 26 <%= movie.title %> 27 <br> 28 # この部分がデータベースに記録されたURLの末尾11桁から動画をサムネイルで引っ張って来るためのコード 29 <iframe width="560" height="315" src="https://www.youtube.com/embed/<%= movie.youtube_url %>" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> 30 <br> 31 <%= link_to 'Show', movie %> 32 <br> 33 <%= link_to 'Edit', edit_movie_path(movie) %> 34 <br> 35 <%= link_to 'Destroy', movie, method: :delete, data: { confirm: 'Are you sure?' } %> 36 <br> 37 </div> 38 </div> 39 <% end %> 40 </div> 41</div> 42 43<br> 44 45<%= link_to 'New Movie', new_movie_path %> 46<%= paginate @movies %>
とりあえず原因となりそうなソースコードを列挙してみましたが、
原因になりそうなコードがまだ不足していたらすみません。
指摘していただければ追記させていただきます。
試したこと
kaminariの初期設定のために
$ bin/rails g kaminari:config
や
$ bin/rails g kaminari:views default
をして
ERB
1# app/views/kaminari/_paginator.html.erb 2 3<%# The container tag 4 - available local variables 5 current_page: a page object for the currently displayed page 6 # ここにtotal_pagesという項目がある。 7 total_pages: total number of pages 8 per_page: number of items to fetch per page 9 remote: data-remote 10 paginator: the paginator that renders the pagination tags inside 11-%> 12<%= paginator.render do -%> 13 <nav class="pagination" role="navigation" aria-label="pager"> 14 <%= first_page_tag unless current_page.first? %> 15 <%= prev_page_tag unless current_page.first? %> 16 <% each_page do |page| -%> 17 <% if page.display_tag? -%> 18 <%= page_tag page %> 19 <% elsif !page.was_truncated? -%> 20 <%= gap_tag %> 21 <% end -%> 22 <% end -%> 23 <% unless current_page.out_of_range? %> 24 <%= next_page_tag unless current_page.last? %> 25 <%= last_page_tag unless current_page.last? %> 26 <% end %> 27 </nav> 28<% end -%>
にてtotal_pages
という項目を見付けることは出来ましたがこれをどう活用して良いのか分かりませんでした。
補足情報(FW/ツールのバージョンなど)
Ruby 2.6.3
Rails 5.2.4.1
devise (4.7.1)
kaminari (1.2.0)
kaminari-actionview (1.2.0)
kaminari-activerecord (1.2.0)
参考にした記事など
リレーションやタグ関連の実装に関してはこの記事を参考にさせていただきました。
railsでタグ検索機能を実装し多対多を理解する - Qiita
動画の埋め込みに関するコードについてはこの記事を参考にしています
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。