ご回答いただけるとありがたいです。よろしくお願いします!
###アプリ概要
勉強の問題をシェアするアプリを作っています。ユーザーはコンテンツ(「学年・教科・カテゴリー・問題・答え・解説」を入力)を投稿することができます。トップページでは自分のコンテンツのみが表示されます。他ユーザーのユーザー詳細ページに遷移すれば、そのユーザーが投稿したコンテンツを見ることができます。
検索機能を使えば、該当するコンテンツのみを表示させることができます。
実現したいこと
ユーザー1の詳細ページでキーワード検索をしたら、ユーザー1の該当するコンテンツのみ表示。
ユーザー2の詳細ページでキーワード検索をしたら、ユーザー2の該当するコンテンツのみ表示。
というようにユーザーの詳細ページで検索をしたら、そのユーザーが投稿したコンテンツだけを検索結果として表示する実装がしたいです。
現状
以下を参考にransackを用いて、検索機能の実装を行いました。
検索機能の実装
Gem、ransackで複数カラム+条件から検索する
トップページでの検索は期待通りの実装をすることができました。
「学年」を選び検索をしたら、該当する学年のコンテンツのみ表示できます。
「教科」「カテゴリー」も同様に検索できます。
該当のソースコード
routes
1Rails.application.routes.draw do 2 devise_for :users 3 root to: "contents#index" 4 resources :contents 5 resources :users, only: [:show, :edit, :update] 6end
controller
1#contents 2def index 3 @q = current_user.contents.ransack(params[:q]) 4 @contents = @q.result.order("created_at DESC").includes([:rich_text_question], :answers) 5end
views
1#contents/index 2<%= search_form_for @q do |f| %> 3 <div class="main-search"> 4 <div class="main-search-container"> 5 <div class="main-search-grade"> 6 <%= f.collection_select :grade_id_eq, Grade.where.not(id: 1), :id, :name, include_blank: "学 年" %> 7 </div> 8 <div class="main-search-subject"> 9 <%= f.collection_select :subject_id_eq, Subject.where.not(id: 1), :id, :name, include_blank: "教 科" %> 10 </div> 11 <div class="main-search-category"> 12 <%= f.search_field :category_cont, placeholder: "カテゴリーを入力", class: "search-textarea" %> 13 </div> 14 <label class="main-search-btn"> 15 <i class="fa fa-search fa-fw"></i> 16 <%= f.submit class: "hidden" %> 17 </label> 18 </div> 19 </div> 20 <% if @contents.present? %> 21 <div class="main-contents"> 22 <%= render partial: "content", collection: @contents %> 23 </div> 24 <% else %> 25 <div class="content-empty-message"> 26 一致するコンテンツがありません。 27 </div> 28 <% end %> 29<% end %>
ここまでがトップページの検索に関する記述です。
次に、ユーザー1がユーザー2の詳細ページに遷移しユーザー2のコンテンツだけを検索できるように以下のように実装しました。
controller
1#user 2def show 3 @user = User.find(params[:id]) 4 @q = @user.contents.ransack(params[:q]) 5 @contents = @q.result.order("created_at DESC").includes([:rich_text_question], :answers) 6end
views
1#user/show 2(省略) 3<%= search_form_for @q do |f| %> 4 <div class="main-search"> 5 <div class="main-search-container"> 6 <div class="main-search-grade"> 7 <%= f.collection_select :grade_id_eq, Grade.where.not(id: 1), :id, :name, include_blank: "学 年" %> 8 </div> 9 <div class="main-search-subject"> 10 <%= f.collection_select :subject_id_eq, Subject.where.not(id: 1), :id, :name, include_blank: "教 科" %> 11 </div> 12 <div class="main-search-category"> 13 <%= f.search_field :category_cont, placeholder: "カテゴリーを入力", class: "search-textarea" %> 14 </div> 15 <label class="main-search-btn"> 16 <i class="fa fa-search fa-fw"></i> 17 <%= f.submit class: "hidden" %> 18 </label> 19 </div> 20 </div> 21 <div class="user-show-contents"> 22 <%= render partial: "contents/content", collection: @contents %> 23 </div> 24<% end %>
###起きた問題
ユーザー1がユーザー2の詳細ページ内にある検索フォームを選択・入力し、検索ボタンを押すとユーザー1のコンテンツで該当するものが表示されます。
もう少し詳しくいうと、他のユーザーの詳細ページで「中1」「英語」と学年・教科を選択し、検索ボタンを押したら、そのユーザーのコンテンツではなく、current_userのコンテンツの「中1」「英語」に該当するコンテンツが表示されます。
これをそのページのユーザーのコンテンツを表示するために、以下を参考に色々試してみました。
ransackを利用した色々な検索フォーム作成方法まとめ
###試したこと1
views
1<%= f.collection_select :grade_id_in, Grade.where.not(id: 1), :id, :name, include_blank: "学 年" %>
###試したこと2
controller
1def show 2 @q = @user.contents.search(search_params) 3 @contents = @q.result.order("created_at DESC").includes([:rich_text_question], :answers) 4end 5 6(省略) 7 8def search_params 9 params.require(:q).permit(:grade_id_eq, :subject_id_eq, :category).merge(user_id: user.id) 10end
エラー
param is missing or the value is empty: q
###試したこと3
controller
1#user 2def show 3 @q = @user.contents.ransack(params[:q]) 4 @contents = @q.result.order("created_at DESC").includes([:rich_text_question], :answers) 5 binding.pry 6end
binding.pryを用いて、@contentsに含まれている値をターミナルで確認。
[1] pry(#<UsersController>)> @contents Content Load (0.7ms) SELECT `contents`.* FROM `contents` WHERE `contents`.`user_id` = 2 ORDER BY created_at DESC ↳ app/controllers/users_controller.rb:8:in `show' ActionText::RichText Load (0.5ms) SELECT `action_text_rich_texts`.* FROM `action_text_rich_texts` WHERE `action_text_rich_texts`.`record_type` = 'Content' AND `action_text_rich_texts`.`name` = 'question' AND `action_text_rich_texts`.`record_id` IN (5, 2, 1, 3) ↳ app/controllers/users_controller.rb:8:in `show' Answer Load (0.3ms) SELECT `answers`.* FROM `answers` WHERE `answers`.`content_id` IN (5, 2, 1, 3) ↳ app/controllers/users_controller.rb:8:in `show' => [#<Content:0x00007fd863a55210 id: 5, grade_id: 7, subject_id: 5, category: "生物", release_id: 1, user_id: 2, created_at: Wed, 10 Feb 2021 18:36:05 JST +09:00, updated_at: Wed, 10 Feb 2021 18:36:05 JST +09:00>, #<Content:0x00007fd863af66d8 id: 2, grade_id: 2, subject_id: 3, category: "連立方程式", release_id: 2, user_id: 2, created_at: Fri, 05 Feb 2021 20:30:41 JST +09:00, updated_at: Sun, 14 Feb 2021 15:04:37 JST +09:00>, #<Content:0x00007fd863af6520 id: 1, grade_id: 2, subject_id: 6, category: "現在進行形", release_id: 2, user_id: 2, created_at: Fri, 05 Feb 2021 15:12:41 JST +09:00, updated_at: Sun, 14 Feb 2021 15:04:37 JST +09:00>,
@contentsにはしっかりとユーザー2のコンテンツが格納されていることは確認できました。
しかし、その中のものを検索後どのように表示するかがわかりません。
長くなりましたが、以上になります。ご助言いただけると幸いです。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。