
・ Ruby: 2.5.7 Rails: 5.2.4 ・ Vagrant: 2.2.7 -VirtualBox: 6.1 ・ OS: macOS Catalina
The following has been implemented.
・ Slim introduction ・ Introduction of Bootstrap3 ・ Introduction of Font Awesome -Login function implementation ・ Implementation of posting function -Many-to-many category function implementation ・ Multi-layer category function implementation (preparation) ・ Multi-layer category function implementation (seed) ・ [Multi-layer category function implementation (creation form)] (https://qiita.com/matsubishi5/items/4afb4a4f307023126c66) ・ [Multi-layer category function implementation (editing form)] (https://qiita.com/matsubishi5/items/10e61f314f6c56b8690d)
homes_controller.rb
#Postscript
def category_window
  @children = Category.find(params[:parent_id]).children
end
@children = Category.find(params[:parent_id]).children
json.jbuilder fileTerminal
$ touch app/views/homes/category_window.json.jbuilder
ruby:category_window.json.jbuilder
json.array! @children do |children|
  json.id children.id
  json.name children.name
end
get_category_children action to create an array.json.array! @children do |children|
①.json.id children.id
json.name children.name
** ◎ Return value when the mouse is on the parent category (business) **
[
  {
    "id": 2, 
    "name": "Finance"
  },
  {
    "id": 6, 
    "name": "Economy"
  },
  {
    "id": 9, 
    "name": "management"
  },
  {
    "id": 13, 
    "name": "marketing"
  },
]
** ◎ Return value when the mouse is on the child category (finance) **
[
  {
    "id": 3, 
    "name": "stock"
  },
  {
    "id": 4, 
    "name": "exchange"
  },
  {
    "id": 5, 
    "name": "tax"
  },
]
routes.rb
#Postscript
get 'get_category/new', to: 'homes#category_window', defaults: { format: 'json' }
slim:application.html.slim
body
  header
    nav.navbar.navbar-default.navbar-fixed-top
      .container-fluid
        ul.nav.navbar-nav.navbar-right
          li.dropdown role='presentation'
            a.dropdown-toggle data-toggle='dropdown' href='#' role='button' aria-expanded='false'
              i.fas.fa-list-ul
              span
                |Search by category
              span.caret
            ul.dropdown-menu role='menu'
              li role='presentation'
                - Category.where(ancestry: nil).each do |parent|
                  = link_to parent.name, root_path, id: "#{parent.id}", class: 'parent-category'
              br
              li role='presentation' class='children-list'
              br
              li role='presentation' class='grandchildren-list'
** * I will omit how to write Bootstrap. ** **
nil, that is, all the parent categories are extracted and displayed in the pull-down menu.- Category.where(ancestry: nil).each do |parent|
  = link_to parent.name, root_path, id: "#{parent.id}", class: 'parent-category'
li role='presentation' class='children-list'
li role='presentation' class='grandchildren-list'
Terminal
$ touch app/assets/javascripts/category_window.js
category_window.js
$(function() {
  function buildChildHTML(children) {
    let html = `
      <a class="children-category" id="${children.id}" href="/">
        ${children.name}
      </a>
    `;
    return html;
  }
  $('.parent-category').on('mouseover', function() {
    let id = this.id;
    $('.children-category').remove();
    $('.grandchildren-category').remove();
    $.ajax({
      type: 'GET',
      url: '/get_category/new',
      data: {
        parent_id: id,
      },
      dataType: 'json',
    }).done(function(children) {
      children.forEach(function(child) {
        let html = buildChildHTML(child);
        $('.children-list').append(html);
      });
    });
  });
  function buildGrandChildHTML(children) {
    let html = `
      <a class="grandchildren-category" id="${children.id}" href="/">
        ${children.name}
      </a>
    `;
    return html;
  }
  $(document).on('mouseover', '.children-category', function() {
    let id = this.id;
    $.ajax({
      type: 'GET',
      url: '/get_category/new',
      data: {
        parent_id: id,
      },
      dataType: 'json',
    }).done(function(children) {
      children.forEach(function(child) {
        let html = buildGrandChildHTML(child);
        $('.grandchildren-list').append(html);
      });
      $(document).on('mouseover', '.children-category', function() {
        $('.grandchildren-category').remove();
      });
    });
  });
});
function buildChildHTML(children) {
  let html = `
    <a class="children-category" id="${children.id}" href="/">
      ${children.name}
    </a>
  `;
  return html;
}
  $('.parent-category').on('mouseover', function() {
    let id = this.id;
    $('.children-category').remove();
    $('.grandchildren-category').remove();
    $.ajax({
      type: 'GET',
      url: '/get_category/new',
      data: {
        parent_id: id,
      },
      dataType: 'json',
    }).done(function(children) {
      children.forEach(function(child) {
        let html = buildChildHTML(child);
        $('.children-list').append(html);
      });
    });
  });
** ◎ Create an event that fires when the mouse hovers over the parent category. ** **
$('.parent-category').on('mouseover', function() {});
** ◎ Assign the ID sent from category_window.json.jbuilder to the variable. ** **
let id = this.id;
** ◎ For the time being, delete the child category and below. ** **
$('.children-category').remove();
$('.grandchildren-category').remove();
** ◎ Set the variable created earlier in the parameter (parent_id) and execute the category_window action asynchronously. ** **
  $.ajax({
    type: 'GET',
    url: '/get_category/new',
    data: {
      parent_id: id,
    },
    dataType: 'json',
  })
** ◎ If Ajax communication is successful, create HTML for the corresponding child category and display it. ** **
.done(function(children) {
  children.forEach(function(child) {
    var html = buildChildHTML(child);
    $('.children-list').append(html);
  });
});
function buildGrandChildHTML(children) {
  var html = `
    <a class="grandchildren-category" id="${children.id}" href="/">
      ${children.name}
    </a>
  `;
  return html;
}
③, the explanation is omitted)$(document).on('mouseover', '.children-category', function() {
  var id = this.id;
  $.ajax({
    type: 'GET',
    url: '/get_category/new',
    data: {
      parent_id: id,
    },
    dataType: 'json',
  }).done(function(children) {
    children.forEach(function(child) {
      var html = buildGrandChildHTML(child);
      $('.grandchildren-list').append(html);
    });
    $(document).on('mouseover', '.children-category', function() {
      $('.grandchildren-category').remove();
    });
  });
});
If you do not disable turbolinks, the pull-down menu will not work asynchronously, so be sure to disable it.
Recommended Posts