rails 5.2で検索画面を作ってるところです。
検索条件の入力項目として、「カテゴリ」>「サブカテゴリ」と連動するセレクトボックスを追加したいです。
以下を参考にセレクトボックスを追加してみましたが、応用できずにいます・・・。
Ajaxでセレクトボックスの中身が動的に変わるRailsアプリの作り方
rails
1 2 <%= form_with url: items_path, method: :get, local: true do |f| %> 3 4 <% category_options = Category.order(:id).map { |c| [c.name, c.id, data: { children_path: category_sub_categories_path(c) }] } %> 5 <%= f.label :category_id %> <%= label_tag(:category, "", class: 'optional_field') %> 6 <%= select :search, :category_id, category_options, {include_blank: ""}, {class: 'select-parent'} %> 7 8 <% sub_categories = @item.category.try(:sub_categories) || [] %> 9 <% sub_category_options = sub_categories.map { |c| [c.name, c.id] } %> 10 <%= select :search, :sub_category_id, sub_category_options, {include_blank: ""}, {class: 'select-children'} %> 11 12 <%= f.submit "検索" , class: "btn btn-default" %> 13 <% end %> 14
1つ目のselectである「カテゴリ」は、表示され検索も出来ました。
問題は、2つ目のselectを作る部分です。
参考先では、下のように@itemを使っています。
ruby
1<% sub_categories = @item.category.try(:sub_categories) || [] %>
今回作りたいのは検索フォームなので、関連するオブジェクトは不要かと思います。
この部分をどう記述すれば良いのでしょうか?
ruby
1f.category. 2や 3Item.category.
とすると、違うようで下のエラーになります。
ActionView::Template::Error (undefined method `category' for #<ActionView::Helpers::FormBuilder:0x00007f88584ff8e8>):
それともここは、検索フォームですがコントローラから、
ruby
1def index 2 @item = Item.new 3end
して
@itemを渡してあげるべきなのでしょうか?
初心者につき的外れの質問しているかもしれませんが、どうかアドバイス宜しくお願いします。
ご指摘により
以下から不足情報を追加
カテゴリモデル
ruby
1class Category < ApplicationRecord 2 has_many :sub_categories 3 has_many :items 4 default_scope -> { order(:order_number) } 5end 6
サブカテゴリモデル
ruby
1class SubCategory < ApplicationRecord 2 belongs_to :category 3 has_many :items 4 default_scope -> { order(:order_number) } 5end 6
アイテムモデル※検索したい対象
ruby
1class Item < ApplicationRecord 2 3 belongs_to :category 4 belongs_to :sub_category 5 6 7 scope :search, ->(search_params) do 8 return if search_params.blank? 9 10 keyword_like(search_params[:keyword]) 11 .category_id_is(search_params[:category_id]) 12 .sub_category_id_is(search_params[:sub_category_id]) 13 end 14 scope :keyword_like, -> (keyword) { where('description LIKE ? or title LIKE ?', "%#{keyword}%","%#{keyword}%") if keyword.present? } 15 scope :category_id_is, -> (category_id) { where(category_id: category_id) if category_id.present? } 16 scope :sub_category_id_is, -> (sub_category_id) { where(sub_category_id: sub_category_id) if sub_category_id.present? } 17 18 19 20end 21
不足情報を追加
コントローラ
ruby
1 2class SubCategoriesController < ApplicationController 3 def index 4 5 @sub_categories = SubCategory.where(category_id: params[:category_id]) 6 7 respond_to do |format| 8 format.html do 9 end 10 11 format.js do 12 render json: @sub_categories.select(:id, :name) 13 end 14 end 15 16 end 17end 18
coffeescript
coffeescript
1$(document).on 'turbolinks:load', -> 2 replaceSelectOptions = ($select, results) -> 3 $select.html $('<option>') 4 $.each results, -> 5 option = $('<option>').val(this.id).text(this.name) 6 $select.append(option) 7 8 replaceChildrenOptions = -> 9 childrenPath = $(@).find('option:selected').data().childrenPath 10 $selectChildren = $(@).closest('form').find('.select-children') 11 if childrenPath? 12 $.ajax 13 url: childrenPath 14 dataType: "json" 15 success: (results) -> 16 replaceSelectOptions($selectChildren, results) 17 error: (XMLHttpRequest, textStatus, errorThrown) -> 18 console.error("Error occurred in replaceChildrenOptions") 19 console.log("XMLHttpRequest: #{XMLHttpRequest.status}") 20 console.log("textStatus: #{textStatus}") 21 console.log("errorThrown: #{errorThrown}") 22 else 23 replaceSelectOptions($selectChildren, []) 24 25 $('.select-parent').on 26 'change': replaceChildrenOptions
分かった所までを追加
その後分かった所までを追記致します。
エラーログはブラウザ、サーバともに出てませんでした。
ただ、正常な流れは、
親(Category)のセレクトボックスを変更で
スクリプトのreplaceChildrenOptions = ->に飛ぶのに対し、
今回のこの画面は、
replaceChildrenOptions = ->に飛びません。
replaceChildrenOptions = ->の真下にalertで確認しました。
ここからまったく分かりません・・・。
htmlを追加
出力されてるhtmlを追記致します
html
1 2<select class="select-parent" name="search[category_id]" id="search_category_id"> 3 <option value=""></option> 4 <option data-children-path="/categories/1/sub_categories" value="1">野菜</option> 5 <option data-children-path="/categories/2/sub_categories" value="2">果物</option> 6 <option data-children-path="/categories/3/sub_categories" value="3">お肉</option> 7 <option data-children-path="/categories/4/sub_categories" value="4">魚介</option> 8</select> 9 10<select class="select-children" name="search[sub_category_id]" id="search_sub_category_id"> 11 <option value=""></option> 12 <option value="1">キャベツ</option> 13 <option value="2">人参</option> 14 <option value="3">玉ねぎ</option> 15 <option value="4">ブロッコリー</option> 16 <option value="5">もやし</option> 17 <option value="6">レタス</option> 18 <option value="7">トマト</option> 19</select> 20
以下は登録画面のhtmlです。
こちらでも同じセレクトボックス連動を使用しており、こちらは正常に動作済みです。
html
1 2<select class="select-parent" name="item[category_id]" id="item_category_id"> 3 <option value="">選択して下さい</option> 4 <option data-children-path="/categories/1/sub_categories" value="1">野菜</option> 5 <option data-children-path="/categories/2/sub_categories" value="2">果物</option> 6 <option data-children-path="/categories/3/sub_categories" value="3">お肉</option> 7 <option data-children-path="/categories/4/sub_categories" value="4">魚介</option> 8</select> 9 10<select class="select-children" name="item[sub_category_id]" id="item_sub_category_id"> 11 <option value="">選択して下さい</option> 12</select>
回答1件
あなたの回答
tips
プレビュー