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

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

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

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

Ruby

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

0回答

1043閲覧

【Rails】Ajaxで動的な都道府県セレクトボックスを実現する~ancestryによる多階層構造データ~

pall

総合スコア4

Ruby on Rails 5

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

Ruby

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

1クリップ

投稿2019/10/29 11:07

編集2019/10/29 11:59

実現したいこと

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});

試したこと

知識不足の為どう修正していけばいいのか本当に分かりません。
ぜひともご教授ください。
よろしくお願いいたします。

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問