質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

3回答

2631閲覧

Railsにてransackを用いて検索機能を実施しようとした所、NoMethodError in PostsController#searchが発生しました

iycloud

総合スコア10

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2022/08/14 01:27

編集2022/08/14 05:20

前提

Railsで検索機能を実施していた所、エラーが発生いたしました。

実現したいこと

  • Postモデルに紐づいているコメントを曖昧検索したい
  • 投稿を作成したユーザー名に紐づく投稿を曖昧検索したい

発生している問題・エラーメッセージ

現在、以下2つの検索機能を実装しています。

  • Postモデルに紐づいているコメントを曖昧検索したい
  • 投稿を作成したユーザー名に紐づく投稿を曖昧検索したい

1つ目のPostモデルに紐づいているコメントを曖昧検索にて、値を入力すると、以下のようなエラーが出ます。
2つ目のフォームに入力した時も同様のエラーが発生します。

NoMethodError in PostsController#search undefined method `construct_tables!' for #<ActiveRecord::Associations::JoinDependency:0x00007ff79857cca8 @join_root=#<ActiveRecord::Associations::JoinDependency::JoinBase:0x00007ff79857cb18 @base_klass=Post(id: integer, title: string, body: text, user_id: integer, created_at: datetime, updated_at: datetime), @children=[#<ActiveRecord::Associations::JoinDependency::JoinAssociation:0x00007ff7937fa700 @join_type=Arel::Nodes::OuterJoin, @base_klass=Comment(id: integer, body: text, user_id: integer, post_id: integer, created_at: datetime, updated_at: datetime), @children=[], @reflection=#<ActiveRecord::Reflection::HasManyReflection:0x00007ff79903ecb8 @name=:comments, @scope=nil, @options={:dependent=>:destroy}, @active_record=Post(id: integer, title: string, body: text, user_id: integer, created_at: datetime, updated_at: datetime), @klass=Comment(id: integer, body: text, user_id: integer, post_id: integer, created_at: datetime, updated_at: datetime), @plural_name="comments", @constructable=true, @class_name="Comment", @inverse_name=:post, @foreign_key="post_id", @inverse_of=#<ActiveRecord::Reflection::BelongsToReflection:0x00007ff79abd9978 @name=:post, @scope=nil, @options={}, @active_record=Comment(id: integer, body: text, user_id: integer, post_id: integer, created_at: datetime, updated_at: datetime), @klass=nil, @plural_name="posts", @constructable=true, @foreign_key="post_id">>>], @table=#

該当のソースコード

_header.html.erb

1<nav class="navbar navbar-expand-lg navbar-light bg-light"> 2 <div class="container-fluid"> 3 <a class="navbar-brand" href="/">Post</a> 4 <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> 5 <span class="navbar-toggler-icon"></span> 6 </button> 7 <div class="collapse navbar-collapse" id="navbarSupportedContent"> 8 <%= search_form_for @q, url: search_posts_path do |f| %> 9 <div class="d-flex"> 10 <%= f.search_field :title_or_body_cont_any, class: 'form-control me-2', placeholder: '投稿' %> 11 <%= f.search_field :comments_body_eq, class: 'form-control me-2', placeholder: 'コメント' %> 12 <%= f.search_field :user_profile_name_cont_any, class: 'form-control me-2', placeholder: 'ユーザー' %> 13 <%= f.submit class: 'btn btn-outline-success', value: "Search" %> 14 </div> 15 <% end %> 16 <ul class="navbar-nav mb-2 mb-lg-0 ms-auto"> 17 <% if current_user.present? %> 18 <li class="nav-item"> 19 <%= link_to '投稿一覧', posts_path, class: 'nav-link' %> 20 </li> 21 <li class="nav-item"> 22 <%= link_to '投稿作成', new_post_path, class: 'nav-link' %> 23 </li> 24 <li class="nav-item"> 25 <%= link_to 'ログアウト', logout_path, class: 'nav-link', method: :delete, data: { confirm: 'ログアウトします' } %> 26 </li> 27 <% else %> 28 <li class="nav-item"> 29 <%= link_to 'ユーザー登録', sign_up_path, class: 'nav-link' %> 30 </li> 31 <li class="nav-item"> 32 <%= link_to 'ログイン', login_path, class: 'nav-link' %> 33 </li> 34 <% end %> 35 </ul> 36 </div> 37 </div> 38</nav> 39

posts_controller.rb

1class PostsController < ApplicationController 2 before_action :require_login, only: %i[new create] 3 before_action :set_q, only: %i[index show new create edit update] 4 5 def index 6 @posts = @q.result(distinct: true).includes(:user).order(created_at: :desc).page(params[:page]).per(10) 7 #binding.pry 8 end 9 10 def new 11 @post = Post.new 12 @tag = @post.tags.new 13 end 14 15 def create 16 @post = current_user.posts.new(post_params) 17 tag_list = params[:tags][:name].split(',') 18 @post_tag = params[:tags][:name] 19 #binding.pry 20 if @post.save 21 @post.save_tag(tag_list) 22 #binding.pry 23 redirect_to post_path(@post), success: 'ポストを作成しました' 24 else 25 flash.now[:danger] = 'ポストを作成できませんでした' 26 render :new 27 end 28 end 29 30 def show 31 @post = Post.find(params[:id]) 32 @comment = Comment.new 33 @post_tags = @post.tags 34 end 35 36 def edit 37 @post = current_user.posts.find(params[:id]) 38 @post_tag = @post.tags.pluck(:name).join(',') 39 end 40 41 def update 42 @post = current_user.posts.find(params[:id]) 43 #@post_tag = @post.tags.pluck(:name).join(',') 44 @post_tag = params[:tags][:name] 45 tag_list = params[:tags][:name].split(',') 46 if @post.update(post_params) 47 @post.save_tag(tag_list) 48 redirect_to post_path(@post), success: 'ポストを更新しました' 49 else 50 flash.now[:danger] = 'ポストを更新できませんでした' 51 render :edit 52 end 53 end 54 55 def destroy 56 @post = current_user.posts.find(params[:id]) 57 @post.destroy! 58 redirect_to posts_path, success: 'ポストを削除しました' 59 end 60 61 def search 62 @q = Post.ransack(params[:q]) 63 @posts = @q.result(distinct: true).order(created_at: :desc).page(params[:page]).per(10) 64 #binding.pry 65 end 66 67 private 68 69 def set_q 70 @q = Post.ransack(params[:q]) 71 #binding.pry 72 end 73 74 def post_params 75 params.require(:post).permit(:title, :body, tags_attributes: [:name, :_destroy, :id]) 76 end 77end 78

schema.rb

1ActiveRecord::Schema.define(version: 2022_08_13_052813) do 2 3 create_table "comments", force: :cascade do |t| 4 t.text "body", null: false 5 t.integer "user_id", null: false 6 t.integer "post_id", null: false 7 t.datetime "created_at", precision: 6, null: false 8 t.datetime "updated_at", precision: 6, null: false 9 t.index ["post_id"], name: "index_comments_on_post_id" 10 t.index ["user_id"], name: "index_comments_on_user_id" 11 end 12 13 create_table "post_tags", force: :cascade do |t| 14 t.integer "post_id", null: false 15 t.integer "tag_id", null: false 16 t.datetime "created_at", precision: 6, null: false 17 t.datetime "updated_at", precision: 6, null: false 18 t.index ["post_id", "tag_id"], name: "index_post_tags_on_post_id_and_tag_id", unique: true 19 t.index ["post_id"], name: "index_post_tags_on_post_id" 20 t.index ["tag_id"], name: "index_post_tags_on_tag_id" 21 end 22 23 create_table "posts", force: :cascade do |t| 24 t.string "title", null: false 25 t.text "body", null: false 26 t.integer "user_id", null: false 27 t.datetime "created_at", precision: 6, null: false 28 t.datetime "updated_at", precision: 6, null: false 29 t.index ["user_id"], name: "index_posts_on_user_id" 30 end 31 32 create_table "profiles", force: :cascade do |t| 33 t.string "name", null: false 34 t.integer "user_id", null: false 35 t.datetime "created_at", precision: 6, null: false 36 t.datetime "updated_at", precision: 6, null: false 37 t.index ["user_id"], name: "index_profiles_on_user_id" 38 end 39 40 create_table "tags", force: :cascade do |t| 41 t.string "name", null: false 42 t.datetime "created_at", precision: 6, null: false 43 t.datetime "updated_at", precision: 6, null: false 44 end 45 46 create_table "users", force: :cascade do |t| 47 t.string "email", null: false 48 t.string "password_digest", null: false 49 t.datetime "created_at", precision: 6, null: false 50 t.datetime "updated_at", precision: 6, null: false 51 t.index ["email"], name: "index_users_on_email", unique: true 52 end 53 54 add_foreign_key "comments", "posts" 55 add_foreign_key "comments", "users" 56 add_foreign_key "post_tags", "posts" 57 add_foreign_key "post_tags", "tags" 58 add_foreign_key "posts", "users" 59 add_foreign_key "profiles", "users" 60end

routes.rb

1Rails.application.routes.draw do 2 root 'posts#index' 3 get 'sessions/new' 4 get :sign_up, to: 'users#new' 5 post :sign_up, to: 'users#create' 6 get 'login', to: 'sessions#new' 7 post 'login', to: 'sessions#create' 8 delete 'logout', to: 'sessions#destroy' 9 resources :posts do 10 resources :comments, module: :posts 11 collection do 12 get 'search' 13 end 14 end 15end

post.rb

1class Post < ApplicationRecord 2 belongs_to :user 3 has_many :comments, dependent: :destroy 4 5 has_many :post_tags, dependent: :destroy 6 has_many :tags, through: :post_tags 7 accepts_nested_attributes_for :tags, allow_destroy: true 8 9 validates :title, presence: true 10 validates :body, presence: true 11 12end 13

Gemfile

1ruby '3.0.2' 2gem 'pry-rails' 3gem 'pry-byebug' 4gem 'ransack', '2.3.0'

試したこと

posts_controllerにて値を受け取れないのでは?と思い、以下を記載しました。
が、うまく動かなかったです。

def search_params params.require(:q).permit(:title_or_body_cont_any, :comments_body_cont, :user_profile_name_cont_any) end

補足情報(FW/ツールのバージョンなど)

参考にした情報
Ransackで簡単に検索フォームを作る73のレシピ
https://nekorails.hatenablog.com/entry/2017/05/31/173925

[Rails]ransackで関連するモデル(親や子)のカラムをまたいで検索する方法
https://qiita.com/sew_sou19/items/520d4348b2eaa7bf792c

https://github.com/activerecord-hackery/ransack/issues/1127

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

自己解決

Gemfileの記述を変更したら正常に動きました。

gem 'ransack', '~> 2.3', '>= 2.3.2'

Railsのバージョンとransackの動き?が噛み合っていなかったことが原因のようです?
https://github.com/activerecord-hackery/ransack/issues/1163

投稿2022/08/14 05:17

iycloud

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ありがとうございます。

ご教示いただいた箇所を:title_or_body_contと変更しました。
しかしながら、コメント曖昧検索、ユーザー曖昧検索の動きに変化はなく、引き続き同様のエラーが出る状態です、、、

投稿2022/08/14 04:22

iycloud

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

winterboum

2022/08/14 05:06

「全く同じ」ではなく「同様」の場合は、それを提示してください。
iycloud

2022/08/14 05:19

全く同じでした。 こちら自己解決いたしました。。 winterboumさん、お忙しい中、ご教示いただきありがとうございました。
guest

0

title_or_body_cont_any が気になります title_or_body_contbody_cont_any は大丈夫かと思いますが。
だったらどうやるのか、はおいておいてまず それが原因かどうか それ無しで試してみてはどうでしょうか。

投稿2022/08/14 03:38

winterboum

総合スコア23282

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

winterboum

2022/08/14 05:17

user.rb と profile.rb も載せてください
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問