解決したいこと
非同期の検索機能を実装したい。
状況
想定される流れ
- railsのview中のフォームで入力された文字を取得し、$.ajaxによってrailsのcontrollerに送信。
- controller中で検索した値をjson.jbuilderを通してjavascriptファイルに返す。
- 返された値を用いてrailsのviewファイルに表示する
うまくいっていること
- keyupによる発火。
- railsのcontrollerファイルへのデータ送信
- controllerファイルでの検索機能。format.jsonの直前でインスタンス変数@instrumentsの中には検索された値が含まれていた。
うまくいかないこと
- 流れの2.の部分で返される値がundefined
ソースファイル
search.js
jquery
1$(function () { 2 # 省略。別画面で用いる検索機能に関する記述であるため。 3 4 function instrumentCandidate(result) { 5 var html = `<div class"search-result__instrument-candidate", data-instrument_id="${result.id}">${result.name}</div>`; 6 7 return html; 8 } 9 10 $("#search_instrument_name").on("keyup", function () { 11 var input = $("#search_instrument_name").val(); 12 if (input == "") { 13 $(".content__search-result").empty(); 14 return; 15 } 16 $.ajax({ 17 type: "get", 18 url: "/instruments/search", 19 data: { 20 keyword: input, 21 }, 22 dataType: "json", 23 }).done(function (results) { 24 // ここでコンソール表示をしているresultsがundefinedとなっている 25 console.log(results); 26 $(".content__search-result").empty(); 27 var insertHTML = ""; 28 29 $.each(results, function (i, result) { 30 console.log(result); 31 32 insertHTML += instrumentCandidate(result); 33 if (i == 4) return false; 34 }); 35 36 $(".content__search-result").append(insertHTML); 37 }); 38 }); 39});
routes
rails
1Rails.application.routes.draw do 2# 省略 3 resources :instruments, except: :index do 4 collection do 5 get :search 6 end 7 end 8 resources :tuning_alls, except: :show 9 resources :finger_alls, except: :show 10end
instruments_controller.rb
rails
1class InstrumentsController < ApplicationController 2 def search 3 params[:keyword].strip! 4 keywords = params[:keyword].split(/\s/) 5 @instruments = Instrument.all 6 keywords.each do |keyword| 7 @instruments = @instruments.where("name like ?", "%#{keyword}%") 8 end 9 10 respond_to do |format| 11 # ここでbinding.pryを用いて@instrumentsの中身を調べた値を下に示す。 12 format.html 13 format.json 14 end 15 end 16end
terminal
1 Instrument Load (0.3ms) SELECT `instruments`.* FROM `instruments` WHERE (name like '%b%') 2 ↳ app/controllers/instruments_controller.rb:22 3=> [#<Instrument:0x00007f85ef8d5230 4 id: 1, 5 name: "5strings banjo", 6 total_string: 5, 7 created_at: Thu, 14 May 2020 22:54:09 JST +09:00, 8 updated_at: Thu, 14 May 2020 22:54:09 JST +09:00>]
search
jbuilder
1json.array! @songs do |song| 2 #省略。別の検索機能で用いる記述のため 3end 4json.array! @instruments, :id, :name, :total_string
instrumentテーブル
new.view(参考)
この画面で検索した結果を表示します。
結果データと、ユーザーがフォームで記入した内容をcreateアクションに送信する機能を実装する予定です。
rails
1.content 2 =form_with url: tuning_alls_path, method: :post, local: true do |f| 3 .content__instrument-name 4 =f.text_field :instrument_name, id: "search_instrument_name", placeholder: "楽器名称" 5 =f.text_field :instrument_id, class: "form_blind" 6 .content__search-result 7
仮説と検証
json.jbuilderの記述ミス
理由
コントローラの時点ではインスタンス変数に正常にデータが格納されている。また$.ajaxに接続しているメソッドdone自体は動作しているため、コントローラ→jqueryの間にあるjbuilderファイルが怪しい。
###試した記述
参考サイト
jbuillder
1json.array! @instruments do |instrument| 2 json.id instrument.id 3 json.name, instrument.name 4 json.total_string instrument.total_string 5end
jbuilder
1json.instrument do 2 json.array! instruments, :id, :name, :total_string 3end
結果
変化なし
正直、何が何やらという感じです。
うまく動作している非同期の検索機能のソースを見て比較してみましたが違いも見当たりません。
お力いただけると幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。