[JAVA] [Schienen] Kategoriefunktion

Einführung

In der Anwendungsentwicklung habe ich eine Kategoriefunktion mit einem Edelstein namens Abstammung hinzugefügt und diese zusammengefasst.

Inhaltsverzeichnis

  1. Kategorie auswählen / speichern
  2. Anzeige der Kategoriesuche
  3. Anzeige der Kategoriesuchergebnisse

1. Kategorie auswählen / speichern

カテゴリー選択・保存

Erstellen einer Kategorietabelle

Vorfahren installieren.

gemfile


gem 'ancestry'

Erstellen Sie als Nächstes ein Kategoriemodell.

Terminal
rails g model category

Beschreibe has_ancestry.

app/models/category.rb


class Category < ApplicationRecord
  has_many :posts
  has_ancestry
end

Beschreiben Sie es in der Migrationsdatei wie folgt. Für den Index klicken Sie hier (https://qiita.com/seiya1121/items/fb074d727c6f40a55f22)

db/migrate/20XXXXXXXXXXXX_create_categories.rb


class CreateCategories < ActiveRecord::Migration[6.0]
  def change
    create_table :categories do |t|
      t.string :name,     index: true, null: false
      t.string :ancestry, index: true
      t.timestamps
    end
  end
end

Ich werde die Kategorie in der Google-Tabelle beschreiben. Die A-Spalte ist id, die B-Spalte ist name (Kategoriename) und die C-Spalte ist Abstammung (numerischer Wert, der Eltern und Nachkommen unterscheidet). Sie können die Daten speichern, indem Sie die Schritte Datei → Herunterladen → durch Kommas getrennte Werte (aktuelles CSV-Blatt) ausführen.

カテゴリー記述例 カテゴリー記述例

Legen Sie die heruntergeladene CSV-Datei im Ordner db ab.

Beschreiben Sie Folgendes in der Datei seeds.rb.

db/seeds.rb 


require "csv"

CSV.foreach('db/category.csv') do |row|
  Category.create(:id => row[0], :name => row[1], :ancestry => row[2])
end 

Wenn Sie den Befehl rails db: seed im Terminal ausführen, wird die CSV-Datei gelesen und der DB-Datensatz automatisch generiert. Geben Sie nach foreach die Datei an, die Sie lesen möchten. Die Beschreibung darunter lautet model name.create (Spaltenname => Spalte, die Sie laden möchten). Zeile [0] → Eine Spalte ist id Zeile [1] → Spalte B ist Name (Kategoriename) Zeile [2] → Die Spalte C ist Abstammung (eine Zahl, die Eltern und Nachkommen unterscheidet)

Routing

Stellen Sie das Routing von Kinder- und Enkelkategorien im JSON-Format ein.

config/routes.rb


Rails.application.routes.draw do
  ~Abkürzung~
  resources :posts do
    collection do
      get 'top'
      get 'get_category_children', defaults: { format: 'json' }
      get 'get_category_grandchildren', defaults: { format: 'json' }
      get 'name_search'
    end
  ~Abkürzung~
end

Regler

Definieren Sie eine übergeordnete Kategorie für den Posts-Controller. Da es an mehreren Stellen verwendet wird, wird es mit before_action definiert.

app/controllers/posts_controller.rb


def set_parents
  @parents = Category.where(ancestry: nil)
end

Definieren Sie Methoden für Kinder- und Enkelkategorien im Post-Controller.

app/controllers/posts_controller.rb


def get_category_children
  @category_children = Category.find("#{params[:parent_id]}").children
end

def get_category_grandchildren
  @category_grandchildren = Category.find("#{params[:child_id]}").children
end

Erstellen Sie eine json.jbuilder-Datei und konvertieren Sie sie in json-Daten.

ruby:app/views/posts/get_category_children.json.jbuilder 


json.array! @category_children do |child|
  json.id child.id
  json.name child.name
end

ruby:app/views/posts/get_category_grandchildren.json.jbuilder 


json.array! @category_grandchildren do |grandchild|
  json.id grandchild.id
  json.name grandchild.name
end

Aussicht

Legen Sie das Verhalten bei der Auswahl einer Kategorie mit Javascript fest.

:app/javascript/category_post.js
$(function(){
  function appendOption(category){
    var html = `<option value="${category.id}">${category.name}</option>`;
    return html;
  }
  function appendChildrenBox(insertHTML){
    var childSelectHtml = "";
    childSelectHtml = `<div class="category__child" id="children_wrapper">
                        <select id="child__category" name="post[category_id]" class="serect_field">
                          <option value="">---</option>
                          ${insertHTML}
                        </select>
                      </div>`;
    $('.append__category').append(childSelectHtml);
  }
  function appendGrandchildrenBox(insertHTML){
    var grandchildSelectHtml = "";
    grandchildSelectHtml = `<div class="category__child" id="grandchildren_wrapper">
                              <select id="grandchild__category" name="post[category_id]" class="serect_field">
                                <option value="">---</option>
                                ${insertHTML}
                                </select>
                            </div>`;
    $('.append__category').append(grandchildSelectHtml);
  }

  $('#item_category_id').on('change',function(){
    var parentId = document.getElementById('item_category_id').value;
    if (parentId != ""){
      $.ajax({
        url: '/posts/get_category_children/',
        type: 'GET',
        data: { parent_id: parentId },
        dataType: 'json'
      })
      .done(function(children){
        $('#children_wrapper').remove();
        $('#grandchildren_wrapper').remove();
        var insertHTML = '';
        children.forEach(function(child){
          insertHTML += appendOption(child);
        });
        appendChildrenBox(insertHTML);
        if (insertHTML == "") {
          $('#children_wrapper').remove();
        }
      })
      .fail(function(){
        alert('Die Kategorie konnte nicht abgerufen werden');
      })
    }else{
      $('#children_wrapper').remove();
      $('#grandchildren_wrapper').remove();
    }
  });
  $('.append__category').on('change','#child__category',function(){
    var childId = document.getElementById('child__category').value;
    if(childId != ""){
      $.ajax({
        url: '/posts/get_category_grandchildren',
        type: 'GET',
        data: { child_id: childId },
        dataType: 'json'
      })
      .done(function(grandchildren){
        $('#grandchildren_wrapper').remove();
        var insertHTML = '';
        grandchildren.forEach(function(grandchild){
          insertHTML += appendOption(grandchild);
        });
        appendGrandchildrenBox(insertHTML);
        if (insertHTML == "") {
          $('#grandchildren_wrapper').remove();
        }
      })
      .fail(function(){
        alert('Die Kategorie konnte nicht abgerufen werden');
      })
    }else{
      $('#grandchildren_wrapper').remove();
    }
  })
});

Zeigen Sie das Auswahlfeld für die Kategorie auf der neuen Beitragsseite an.

ruby:app/views/posts/new.html.erb


<div class="append__category">
  <div class="category">
    <div class="form__label">
      <div class="weight-bold-text lavel__name ">
Kategorie
      </div>
      <div class="lavel__Required">
        <%= f.collection_select :category_id, @parents, :id, :name,{ include_blank: "Bitte auswählen"},class:"serect_field", id:"item_category_id" %>
      </div>
    </div>
  </div>
</div>

2. Anzeige der Kategoriesuche

カテゴリー検索表示

Regler

app/controllers/posts_controller.rb


def top
  respond_to do |format|
    format.html
    format.json do
      if params[:parent_id]
        @childrens = Category.find(params[:parent_id]).children
      elsif params[:children_id]
        @grandChilds = Category.find(params[:children_id]).children
      elsif params[:gcchildren_id]
        @parents = Category.where(id: params[:gcchildren_id])
      end
    end
  end
end

Aussicht

In Javascript erhalten wir die untergeordnete Kategorie und die Enkelkategorie, die zu der übergeordneten Kategorie gehören, in der sich die Maus befindet.

:app/javascript/category.js
$(document).ready(function () {
  //Übergeordnete Kategorie anzeigen
  $('#categoBtn').hover(function (e) {
    e.preventDefault();
    e.stopPropagation();
    $('#tree_menu').show();
    $('.categoryTree').show();
  }, function () {
    //Ich wage nichts zu schreiben
  });

  //Zeigen Sie Header-Kategorien asynchron an
  function childBuild(children) {
    let child_category = `
                        <li class="category_child">
                          <a href="/posts/${children.id}/search"><input class="child_btn" type="button" value="${children.name}" name= "${children.id}">
                          </a>
                        </li>
                        `
    return child_category;
  }

  function gcBuild(children) {
    let gc_category = `
                        <li class="category_grandchild">
                          <a href="/posts/${children.id}/search"><input class="gc_btn" type="button" value="${children.name}" name= "${children.id}">
                          </a>
                        </li>
                        `
    return gc_category;
  }

  //Übergeordnete Kategorie anzeigen
  $('#categoBtn').hover(function (e) {
    e.preventDefault();
    e.stopPropagation();
    timeOut = setTimeout(function () {
      $('#tree_menu').show();
      $('.categoryTree').show();
    }, 500)
  }, function () {
    clearTimeout(timeOut)
  });

  //Untergeordnete Kategorien anzeigen
  $('.parent_btn').hover(function () {
    $('.parent_btn').css('color', '');
    $('.parent_btn').css('background-color', '');
    let categoryParent = $(this).attr('name');
    timeParent = setTimeout(function () {
      $.ajax({
          url: '/posts/top',
          type: 'GET',
          data: {
            parent_id: categoryParent
          },
          dataType: 'json'
        })
        .done(function (data) {
          $(".categoryTree-grandchild").hide();
          $(".category_child").remove();
          $(".category_grandchild").remove();
          $('.categoryTree-child').show();
          data.forEach(function (child) {
            let child_html = childBuild(child)
            $(".categoryTree-child").append(child_html);
          });
          $('#tree_menu').css('max-height', '490px');
        })
        .fail(function () {
          alert("Bitte wählen sie eine Kategorie");
        });
    }, 400)
  }, function () {
    clearTimeout(timeParent);
  });

  //Enkelkind Kategorie anzeigen
  $(document).on({
    mouseenter: function () {
      $('.child_btn').css('color', '');
      $('.child_btn').css('background-color', '');
      let categoryChild = $(this).attr('name');
      timeChild = setTimeout(function () {
        $.ajax({
            url: '/posts/top',
            type: 'GET',
            data: {
              children_id: categoryChild
            },
            dataType: 'json'
          })
          .done(function (gc_data) {
            $(".category_grandchild").remove();
            $('.categoryTree-grandchild').show();
            gc_data.forEach(function (gc) {
              let gc_html = gcBuild(gc)
              $(".categoryTree-grandchild").append(gc_html);
              let parcol = $('.categoryTree').find(`input[name="${gc.root}"]`);
              $(parcol).css('color', 'white');
              $(parcol).css('background-color', '#b1e9eb');
            });
            $('#tree_menu').css('max-height', '490px');
          })
          .fail(function () {
            alert("Bitte wählen sie eine Kategorie");
          });
      }, 400)
    },
    mouseleave: function () {
      clearTimeout(timeChild);
    }
  }, '.child_btn');

  //Bei der Auswahl einer Enkelkategorie
  $(document).on({
    mouseenter: function () {
      let categoryGc = $(this).attr('name');
      timeGc = setTimeout(function () {
        $.ajax({
            url: '/posts/top',
            type: 'GET',
            data: {
              gcchildren_id: categoryGc
            },
            dataType: 'json'
          })
          .done(function (gc_result) {
            let childcol = $('.categoryTree-child').find(`input[name="${gc_result[0].parent}"]`);
            $(childcol).css('color', 'white');
            $(childcol).css('background-color', '#b1e9eb');
            $('#tree_menu').css('max-height', '490px');
          })
          .fail(function () {
            alert("Bitte wählen sie eine Kategorie");
          });
      }, 400)
    },
    mouseleave: function () {
      clearTimeout(timeGc);
    }
  }, '.gc_btn');


  //Schaltflächen auf der Kategorielistenseite
  $('#all_btn').hover(function (e) {
    e.preventDefault();
    e.stopPropagation();
    $(".categoryTree-grandchild").hide();
    $(".categoryTree-child").hide();
    $(".category_grandchild").remove();
    $(".category_child").remove();
  }, function () {
    //Wenn Sie nichts schreiben, wird nur die Aktion weitergegeben, wenn sie vom übergeordneten Element abweicht.
  });

  //Kategorie ausblenden(0 aus dem Kategoriemenü.Es verschwindet, wenn der Cursor 8 Sekunden oder länger entfernt wird)
  $(document).on({
    mouseleave: function (e) {
      e.stopPropagation();
      e.preventDefault();
      timeChosed = setTimeout(function () {
        $(".categoryTree-grandchild").hide();
        $(".categoryTree-child").hide();
        $(".categoryTree").hide();
        $(this).hide();
        $('.parent_btn').css('color', '');
        $('.parent_btn').css('background-color', '');
        $(".category_child").remove();
        $(".category_grandchild").remove();
      }, 800);
    },
    mouseenter: function () {
      timeChosed = setTimeout(function () {
        $(".categoryTree-grandchild").hide();
        $(".categoryTree-child").hide();
        $(".categoryTree").hide();
        $(this).hide();
        $('.parent_btn').css('color', '');
        $('.parent_btn').css('background-color', '');
        $(".category_child").remove();
        $(".category_grandchild").remove();
      }, 800);
      clearTimeout(timeChosed);
    }
  }, '#tree_menu');

  //Verarbeitung von Kategorietasten
  $(document).on({
    mouseenter: function (e) {
      e.stopPropagation();
      e.preventDefault();
      timeOpened = setTimeout(function () {
        $('#tree_menu').show();
        $('.categoryTree').show();
      }, 500);
    },
    mouseleave: function (e) {
      e.stopPropagation();
      e.preventDefault();
      clearTimeout(timeOpened);
      $(".categoryTree-grandchild").hide();
      $(".categoryTree-child").hide();
      $(".categoryTree").hide();
      $("#tree_menu").hide();
      $(".category_child").remove();
      $(".category_grandchild").remove();
    }
  }, '.header__headerInner__nav__listsLeft__item');
});

Stellen Sie das Kategorieauswahlfenster auf dem oberen Bildschirm ein.

ruby:app/views/posts/top.html.erb


  <div class="item-categories">
    <h2>
Kategorieliste
    </h2>
    <%= link_to  posts_path, class: "category-button", id: 'categoBtn' do %>
Suche nach Kategorie
    <% end %>
    <div id="tree_menu">
      <ul class="categoryTree">
        <% @parents.each do |parent| %>
          <li class="category_parent">
            <%= link_to search_post_path(parent) do %>
              <input type="button" value="<%= parent.name %>" name="<%= parent.id %>" class="parent_btn">
            <% end %>
          </li>
        <% end %>
      </ul>
      <ul class="categoryTree-child">
      </ul>
      <ul class="categoryTree-grandchild">
      </ul>
    </div>
  </div>

3. Anzeige der Kategoriesuchergebnisse

カテゴリいー検索結果表示

Routing

Eine Suchaktion wird mithilfe von member definiert, um Kategorien nach ID zu unterscheiden.

config/routes.rb


resources :posts do
    ~Abkürzung~
    member do
      get 'search'
    end
   ~Abkürzung~
end

Regler

Die Kategorie, auf die Sie geklickt haben, hängt davon ab, ob es sich um eine übergeordnete Kategorie, eine untergeordnete Kategorie oder eine Enkelkategorie handelt.

app/controllers/posts_controller.rb


  def search
    @category = Category.find_by(id: params[:id])

    if @category.ancestry == nil
      category = Category.find_by(id: params[:id]).indirect_ids
      if category.empty?
        @posts = Post.where(category_id: @category.id).order(created_at: :desc)
      else
        @posts = []
        find_item(category)
      end

    elsif @category.ancestry.include?("/")
      @posts = Post.where(category_id: params[:id]).order(created_at: :desc)

    else
      category = Category.find_by(id: params[:id]).child_ids
      @posts = []
      find_item(category)
    end
  end

  def find_item(category)
    category.each do |id|
      post_array = Post.where(category_id: id).order(created_at: :desc)
      if post_array.present?
        post_array.each do |post|
          if post.present?
            @posts.push(post)
          end
        end
      end
    end
  end

Aussicht

ruby:app/views/posts/search.html.erb


  <div class="item-categories">
    <h2>
Kategorieliste
    </h2>
    <%= link_to  posts_path, class: "category-button", id: 'categoBtn' do %>
Suche nach Kategorie
    <% end %>
    <div id="tree_menu">
      <ul class="categoryTree">
        <% @parents.each do |parent| %>
          <li class="category_parent">
            <%= link_to search_post_path(parent) do %>
              <input type="button" value="<%= parent.name %>" name="<%= parent.id %>" class="parent_btn">
            <% end %>
          </li>
        <% end %>
      </ul>
      <ul class="categoryTree-child">
      </ul>
      <ul class="categoryTree-grandchild">
      </ul>
    </div>
  </div>

Referenzlink

https://qiita.com/k_suke_ja/items/aee192b5174402b6e8ca https://qiita.com/Sobue-Yuki/items/9c1b05a66ce6020ff8c1
https://qiita.com/dr_tensyo/items/88e8ddf0f5ce37040dc8 https://qiita.com/ATORA1992/items/bd824f5097caeee09678 https://qiita.com/misioro_missie/items/175af1f1678e76e59dea https://qiita.com/Rubyist_SOTA/items/49383aa7f60c42141871

Recommended Posts

[Schienen] Kategoriefunktion
[Rails] Implementierung der Kategoriefunktion
Schienen folgen der Funktion
Implementierung der Funktionsfunktion [Rails] gem ancestry category
[Rails] Benachrichtigungsfunktion
[Rails] Tag-Ranking-Funktion
Implementieren Sie die Anwendungsfunktion in Rails
Implementierung der Fuzzy-Suchfunktion für Schienen
[Schienen] Implementieren Sie die Benutzersuchfunktion
Suchfunktion mit [Rails] Ransack
[Rails] Implementierung einer mehrschichtigen Kategoriefunktion unter Verwendung der Abstammung "Vorbereitung"
[Rails] Implementierung einer mehrschichtigen Kategoriefunktion unter Verwendung der "Seed Edition" der Vorfahren
Schienen ~ Die Nachrichtenfunktion verstehen ~
Implementierung der Kategorie-Pulldown-Funktion
Implementieren Sie die Kategoriefunktion mithilfe von Vorfahren
[Rails] EC-Site-Cart-Funktion
[Rails] Implementierung der Tutorial-Funktion
[Rails] Implementieren Sie die Image-Posting-Funktion
[Rails] Implementierung einer ähnlichen Funktion
[Rails] Implementierung einer mehrschichtigen Kategoriefunktion unter Verwendung der Abstammung "Edit Form Edition"
[Rails] Implementierung einer mehrschichtigen Kategoriefunktion unter Verwendung der Abstammung "Erstellungsformular"
[Rails] Implementierung der CSV-Importfunktion
[Rails] Asynchrone Implementierung der Like-Funktion
[Ruby on Rails] Paging-Funktion eingeführt
[Rails] Implementierung der Bildvorschau
[Rails] Tag-Verwaltungsfunktion (unter Verwendung von Acts-as-Taggable-On)
[Rails] Über die Implementierung der Like-Funktion
[Rails] Implementierung der Benutzerrückzugsfunktion
[Rails] Implementierung der CSV-Exportfunktion
Implementieren Sie eine einfache Anmeldefunktion in Rails
[Ruby on Rails] CSV-Ausgabefunktion
[Rails] Sprachposting-Funktion ~ Cloudinary, CarrierWave
[Rails] Kommentarfunktion (Registrierung / Anzeige / Löschung)
[Rails] Implementierung von Viele-zu-Viele-Kategoriefunktionen
[Ruby on Rails] Implementierung der Kommentarfunktion
[Ruby on Rails] DM, Chat-Funktion
Implementieren Sie die CSV-Download-Funktion in Rails
[Rails] Memo zur Implementierung der Kommentarfunktion
[Ruby on Rails] Suchfunktion (nicht ausgewählt)
[Rails] Hinzufügen der Ruby On Rails-Kommentarfunktion
Rails Grundlagen
Rails Review 1
[Rails] Funktionseinschränkungen im Gerät (Login / Logout)
Rails API
Schienenmigration