実現したいこと
rails初心者です。
ancestryで作成した都道府県データを用いて、選択肢を動的(親・子・孫)に変化させる機能を実装したいと考えております。
【親要素を選択⇒その変化でイベントが発火して子要素のセレクトボックスが作られる⇒その変化で孫要素のセレクトボックスが作られる仕様】
ancestryによる多階層構造データを用いて、動的カテゴリーセレクトボックスを実現するAjax
ユーザーが記事を投稿する際に、記事に対してどの都道府県に関する記事なのかを紐づけたいと考えています。
都道府県のデータは事前にancestryのgemを用いてseed-fuにて作成済みです。
上記の記事を参考に実装したのですが、新規投稿時は問題無く動いているのですが、
編集ページにおいて投稿時に選択した値が入っておらず、親カテゴリーを選択しても、イベントが発火せず子カテゴリーが表示されません。
chromeの検証コンソールにおいて下記のエラーが出てしまっています。
Routing Error No route matches [GET] "/posts/18/get_prefecture_children"
またviewで投稿された都道府県のデータを表示したいと考えているのですが、いろいろと試してみたのですが、うまくいかず困ってしまっています。
postsテーブル多ーprefecturesテーブル1の関係で紐づけております。
コード
routes.rb
ruby
1resources :posts, only: [:index, :show, :new, :create, :edit, :update, :destroy] do 2 3 collection do 4 get 'get_prefecture_children', defaults: { format: 'json' } 5 get 'get_prefecture_grandchildren', defaults: { format: 'json' } 6 end 7 end
posts_controller.rb
ruby
1def new 2 @prefecture_parent_array = ["---"] 3 Prefecture.where(ancestry: nil).each do |parent| 4 @prefecture_parent_array << parent.name 5 end 6 end 7 8def edit 9 @prefecture_parent_array = ["---"] 10 Prefecture.where(ancestry: nil).each do |parent| 11 @prefecture_parent_array << parent.name 12 end 13 14 end 15 16def get_prefecture_children 17 @prefecture_children = Prefecture.find_by(name: "#{params[:parent_name]}", ancestry: nil).children 18 end 19def get_prefecture_grandchildren 20 @prefecture_grandchildren = Prefecture.find("#{params[:child_id]}").children 21 end 22end
get_prefecture_children.json.jbuilder
javascript
1json.array! @prefecture_children do |child| 2 json.id child.id 3 json.name child.name 4end
get_prefecture_grandchildren.json.jbuilder
javascript
1json.array! @prefecture_grandchildren do |grandchild| 2 json.id grandchild.id 3 json.name grandchild.name 4end
edit.html.erb
ruby
1 <div class="listing-form-box"> 2 <div class="listing-post-detail__prefecture"> 3 <%= f.label '都道府県を選択', class: 'listing-default__label' %> 4 <span class="listing-default--require"></span> 5 <div class="listing-select-wrapper"> 6 <div class="listing-select-wrapper__box"> 7 <%= f.select :prefecture, @prefecture_parent_array, {}, {class: 'listing-select-wrapper__box--select', id: 'parent_prefecture'} %> 8 </div> 9 </div> 10 </div> 11 </div>
prefecture.js
javascript
1$(function(){ 2 // カテゴリーセレクトボックスのオプションを作成 3 function appendOption(prefecture){ 4 var html = `<option value="${prefecture.name}" data-prefecture="${prefecture.id}">${prefecture.name}</option>`; 5 return html; 6 } 7 // 子カテゴリーの表示作成 8 function appendChidrenBox(insertHTML){ 9 var childSelectHtml = ''; 10 childSelectHtml = `<div class='listing-select-wrapper__added' id= 'children_wrapper'> 11 <div class='listing-select-wrapper__box'> 12 <select class="listing-select-wrapper__box--select" id="child_prefecture" name="prefecture_id"> 13 <option value="---" data-prefecture="---">---</option> 14 ${insertHTML} 15 <select> 16 </div> 17 </div>`; 18 $('.listing-post-detail__prefecture').append(childSelectHtml); 19 } 20 // 孫カテゴリーの表示作成 21 function appendGrandchidrenBox(insertHTML){ 22 var grandchildSelectHtml = ''; 23 grandchildSelectHtml = `<div class='listing-select-wrapper__added' id= 'grandchildren_wrapper'> 24 <div class='listing-select-wrapper__box'> 25 <select class="listing-select-wrapper__box--select" id="grandchild_prefecture" name="prefecture_id"> 26 <option value="---" data-prefecture="---">---</option> 27 ${insertHTML} 28 </select> 29 </div> 30 </div>`; 31 $('.listing-post-detail__prefecture').append(grandchildSelectHtml); 32 } 33 // 親カテゴリー選択後のイベント 34 $('#parent_prefecture').on('change', function(){ 35 var parentPrefecture = document.getElementById('parent_prefecture').value; //選択された親カテゴリーの名前を取得 36 if (parentPrefecture != "---"){ //親カテゴリーが初期値でないことを確認 37 $.ajax({ 38 url: 'get_prefecture_children', 39 type: 'GET', 40 data: { parent_name: parentPrefecture }, 41 dataType: 'json' 42 }) 43 .done(function(children){ 44 $('#children_wrapper').remove(); //親が変更された時、子以下を削除する 45 $('#grandchildren_wrapper').remove(); 46 $('#size_wrapper').remove(); 47 $('#brand_wrapper').remove(); 48 var insertHTML = ''; 49 children.forEach(function(child){ 50 insertHTML += appendOption(child); 51 }); 52 appendChidrenBox(insertHTML); 53 }) 54 .fail(function(){ 55 alert('カテゴリー取得に失敗しました'); 56 }) 57 }else{ 58 $('#children_wrapper').remove(); //親カテゴリーが初期値になった時、子以下を削除する 59 $('#grandchildren_wrapper').remove(); 60 $('#size_wrapper').remove(); 61 $('#brand_wrapper').remove(); 62 } 63 }); 64 // 子カテゴリー選択後のイベント 65 $('.listing-post-detail__prefecture').on('change', '#child_prefecture', function(){ 66 var childId = $('#child_prefecture option:selected').data('prefecture'); //選択された子カテゴリーのidを取得 67 if (childId != "---"){ //子カテゴリーが初期値でないことを確認 68 $.ajax({ 69 url: 'get_prefecture_grandchildren', 70 type: 'GET', 71 data: { child_id: childId }, 72 dataType: 'json' 73 }) 74 .done(function(grandchildren){ 75 if (grandchildren.length != 0) { 76 $('#grandchildren_wrapper').remove(); //子が変更された時、孫以下を削除する 77 $('#size_wrapper').remove(); 78 $('#brand_wrapper').remove(); 79 var insertHTML = ''; 80 grandchildren.forEach(function(grandchild){ 81 insertHTML += appendOption(grandchild); 82 }); 83 appendGrandchidrenBox(insertHTML); 84 } 85 }) 86 .fail(function(){ 87 alert('カテゴリー取得に失敗しました'); 88 }) 89 }else{ 90 $('#grandchildren_wrapper').remove(); //子カテゴリーが初期値になった時、孫以下を削除する 91 $('#size_wrapper').remove(); 92 $('#brand_wrapper').remove(); 93 } 94 }); 95});
試したこと
知識不足の為どう修正していけばいいのか本当に分かりません。
ぜひともご教授ください。
よろしくお願いいたします。
あなたの回答
tips
プレビュー