🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails 5

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

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

2248閲覧

Rails form_forで検索機能を実装したが、検索結果が正しくビューに表示されない

TakahiroShoji

総合スコア7

Ruby on Rails 5

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

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2019/12/13 08:48

編集2019/12/14 03:33

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
ruby on railsでYahoo!知恵袋のようなシステムを作っています。
記事検索機能を実装中に以下のエラーが発生しました。

原因と解決策をご教示お願いいたします。

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

検索ボタンを押下しても検索結果が現れず、全ての投稿が表示される models/post.rbで記載してあるsearchメソッドがいかなる場合でもPost.allを取得してしまう

該当のソースコード

models/post.rb

class Post < ApplicationRecord attr_accessor :keyword has_many :comments belongs_to :user def self.search(search) return Post.all unless search Post.where('text LIKE(?)', "%#{search}%") end end

views/posts/searches/index.html.haml

.contents .content__title 検索結果 - @posts.each do |post| = render partial: "shared/post", locals: { post: post }

views/posts/shared/_post.html.haml

.content .content__upper .content__upper-icon = icon('fas', 'user-alt', class: 'icon') .content__upper__right .content__upper__right-name = link_to post.user.name, user_path(post.user), class: "content__upper__right-name" .content__upper__right__element .content__upper__right__element-industry - if post.industry? 希望業界: = post.industry .content__upper__right__element-hopejob - if post.hopejob? 希望職種: = post.hopejob .content__upper__right__element-nowjob - if post.nowjob? 現職: = post.nowjob .content__upper__right-date = post.created_at.strftime("%Y/%m/%d(%a) %H:%M") .content__lower %p.content__lower__text = link_to post.text.truncate(200), post_path(post.id), class: "content__lower__text"

controllers/posts_controller.rb

class PostsController < ApplicationController before_action :set_post, only: [:edit, :show] def index @post = Post.new @posts = Post.includes(:user).page(params[:page]).per(5).order("created_at DESC") end 〜 中略 〜 def search @posts = Post.search(params[:keyword]) end private def post_params params.require(:post).permit(:industry,:hopejob ,:nowjob, :text, :solved_status).merge(user_id: current_user.id) end def set_post @post = Post.find(params[:id]) end end

controllers/posts/searches_controller.rb

class Posts::SearchesController < ApplicationController def index @post = Post.new @posts = Post.search(params[:keyword]) end end

config/routes

Rails.application.routes.draw do devise_for :users root "posts#index" namespace :posts do resources :searches, only: :index end resources :posts do resources :comments, only: :create end end

###追加情報
views/layouts/application.html.haml

%body %header.header .header__title = link_to "Self PR", root_path, class: "header__title--text" = form_for(@post, url: posts_searches_path, method: :get, class: "search-form") do |f| = f.text_field :keyword, placeholder: "記事を検索する", class: "search-form__input" = icon('fas', 'search', class: 'search-icon') = f.submit "検索", class: "search-form__btn" .header__right - if user_signed_in? = link_to current_user.name, user_path(current_user), class: "header__right--btn" = link_to "新規投稿", new_post_path, class: "header__right--btn" = link_to "ログアウト", destroy_user_session_path, method: :delete, class: "header__right--btn" - else = link_to "ログイン", new_user_session_path, class: "header__right--btn" = link_to "新規登録", new_user_registration_path, class: "header__right--btn" = yield

sampleと検索時のターミナルのログ

Started GET "/posts/searches?utf8=%E2%9C%93&post%5Bkeyword%5D=sample&commit=%E6%A4%9C%E7%B4%A2" for ::1 at 2019-12-14 12:31:19 +0900 Processing by Posts::SearchesController#index as HTML Parameters: {"utf8"=>"✓", "post"=>{"keyword"=>"sample"}, "commit"=>"検索"} User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 ORDER BY `users`.`id` ASC LIMIT 1 Rendering posts/searches/index.html.haml within layouts/application Post Load (0.2ms) SELECT `posts`.* FROM `posts` User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 Rendered shared/_post.html.haml (5.5ms) CACHE (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 [["id", 2], ["LIMIT", 1]] Rendered shared/_post.html.haml (1.3ms) CACHE (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 [["id", 2], ["LIMIT", 1]] Rendered shared/_post.html.haml (1.7ms) Rendered posts/searches/index.html.haml within layouts/application (16.2ms) Completed 200 OK in 58ms (Views: 52.6ms | ActiveRecord: 0.7ms)

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

Rails 5.0.7.2
form_forメソッドを使用しています。

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

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

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

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

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

guest

回答2

0

ベストアンサー

searchメソッドに引数を渡すところを、

ruby

1@posts = Post.search(params[:post][:keyword])

としてみたらどうでしょうか?

投稿2019/12/14 07:16

clora

総合スコア72

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

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

TakahiroShoji

2019/12/14 07:25

指示通りのコードで無事解決いたしました。 ありがとうございます。 form_forは関連するモデルがあるヘルパーメソッドのため、モデルのいらない記述で実装しようと考えていましたが、助かりました。 (参考までに http://tanihiro.hatenablog.com/entry/2014/01/09/193720)
clora

2019/12/14 07:42

よかったです。 値がきちんと渡せているかどうかを確かめるときはbinding pryを使うと便利ですよ。 下記のように記述して、確かめてみると、nilになってしまっているのがわかると思います。 def index binding pry @posts = Post.search(params[:keyword]) end [1] pry(#<Posts::SearchesController>)> params[:post][:keyword] => "sample" [2] pry(#<Posts::SearchesController>)> params[:keyword] => nil
guest

0

提示されているviewには params[:keyword] を返す場所が見当たりません。
つまり
いかなる場合も params[:keyword] がnilなので、いかなる場合でもPost.allを取得してしまいます。

投稿2019/12/13 22:51

winterboum

総合スコア23567

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

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

TakahiroShoji

2019/12/14 00:45

ご回答ありがとうございます。 今回の表示先のビュー`views/posts/searches/index.html.haml`には`controllers/posts/searches_controller.rb`にて@postsと定義したインスタンス変数が利用されているため、`params[:keyword]`を取得できていると考えていました。 具体的にはビューのどの箇所を修正すれば、正しく`params[:keyword]`を取得できますでしょうか?
winterboum

2019/12/14 01:45

そもそも検索ワードはどこに入力するのでしょう?
TakahiroShoji

2019/12/14 02:21

失礼いたしました。 `application.html.haml`の中にて、固定ヘッダー部分に検索フォームを作成いたしました。 views/layouts/application.html.haml ``` %body %header.header .header__title = link_to "Self PR", root_path, class: "header__title--text" = form_for(@post, url: posts_searches_path, method: :get, class: "search-form") do |f| = f.text_field :keyword, placeholder: "記事を検索する", class: "search-form__input" = icon('fas', 'search', class: 'search-icon') = f.submit "検索", class: "search-form__btn" .header__right - if user_signed_in? = link_to current_user.name, user_path(current_user), class: "header__right--btn" = link_to "新規投稿", new_post_path, class: "header__right--btn" = link_to "ログアウト", destroy_user_session_path, method: :delete, class: "header__right--btn" - else = link_to "ログイン", new_user_session_path, class: "header__right--btn" = link_to "新規登録", new_user_registration_path, class: "header__right--btn" = yield ```
winterboum

2019/12/14 03:11

このcode質問の方に移しておいて下さい。 で、これで駄目ですか。。。。 検索かけた時のlog見せて下さい
TakahiroShoji

2019/12/14 03:35

初めての質問のため、コメントのやりとりでご不便おかけし申し訳ございませんでした。 質問欄に追記しましたので、ご確認いただけますと幸いです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問