[RUBY] [Rails] Fonction de recherche et de liste de produits à partir de catégories à plusieurs niveaux

Aperçu

Comme le montre l'image ci-dessous, il s'agit d'une fonction permettant d'afficher une liste de produits appartenant à la catégorie sélectionnée. Les catégories sont à plusieurs niveaux et plus le niveau est bas, plus la recherche est restreinte. Les catégories sont créées en utilisant l'ascendance des gemmes. d3a7f46ab307f384f41fe88f3917826b.gif

supposition

-Une table de catégorie est créée en utilisant l'ascendance. ・ Catégorie: Produit = 1: Il existe de nombreuses relations. -L'identifiant de catégorie le plus bas est enregistré dans le category_id du modèle de produit.

L'application de cet article utilise trois niveaux de catégories. En outre, dans cet article, la catégorie supérieure est la «catégorie parent» et la hiérarchie en dessous est la «catégorie enfant». En dessous, cela est exprimé comme la «catégorie des petits-enfants».

Article de référence

Les articles suivants seront utiles pour savoir comment installer l'ascendance. https://qiita.com/Sotq_17/items/120256209993fb05ebac https://qiita.com/pdm21/items/fe0055b3190af790f1c0

la mise en oeuvre

Page de liste de catégories

Tout d'abord, nous allons créer une page de liste qui affiche toutes les catégories. Utilisez l'action d'index du contrôleur de catégories. bda976886433b175ea19e2cecab7afa1.png

définition de l'action d'index

app/controllers/categories_controller.rb


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

Puisque la colonne d'ascendance de la catégorie parent est nulle, vous pouvez obtenir la catégorie parent avec la description ci-dessus.

Voir la création

app/views/categories/index.html.haml


%liste des catégories h1
%ul.categories
  - @parents.each do |parent|
    %li.parents= link_to "#{parent.name}", category_path(parent)
    
    %ul.categories__children
      - parent.children.each do |child|
        %li.childern= link_to "#{child.name}", category_path(child)

        %ul.categories__grandchildren
          - child.children.each do |grandchild|
            %li= link_to "#{grandchild.name}", category_path(grandchild)

Vous pouvez maintenant lister toutes les catégories. Chaque nom de catégorie est lié à la page de liste de produits par catégorie décrite plus loin.

Liste de produits page par catégorie

Ensuite, nous allons créer une page qui répertorie les produits appartenant à la catégorie sélectionnée. Utilisez l'action show du contrôleur de catégories.

afficher la définition de l'action

app/controllers/categories_controller.rb


before_action :set_category, only: :show

def show
  @items = @category.set_items
  @items = @items.where(buyer_id: nil).order("created_at DESC").page(params[:page]).per(9)
end

private
def set_category
  @category = Category.find(params[:id])
end

Récupérez les produits de la catégorie par la méthode de modèle set_items décrite plus loin.

Définition de la méthode du modèle

app/models/category.rb


has_many :items
has_ancestry

def set_items
  #Pour la catégorie parent
  if self.root?
    start_id = self.indirects.first.id
    end_id = self.indirects.last.id
    items = Item.where(category_id: start_id..end_id)
    return items

    #Pour les catégories enfants
  elsif self.has_children?
    start_id = self.children.first.id
    end_id = self.children.last.id
    items = Item.where(category_id: start_id..end_id)
    return items

    #Pour la catégorie petits-enfants
  else
    return self.items
  end
end

L'identifiant de la catégorie petit-enfant est enregistré dans le category_id du produit. Par conséquent, si vous écrivez simplement @items = @ category.items, vous ne pouvez obtenir les informations sur le produit que lorsque @category est un petit-enfant. Par conséquent, comme décrit ci-dessus, le branchement conditionnel est effectué en fonction du parent, de l'enfant ou du petit-enfant auquel la catégorie correspond. Si la catégorie est parent ou enfant, le produit est acquis en spécifiant la plage d'identifiants de la catégorie petit-enfant dont il est propriétaire.

Les articles suivants seront utiles lors de l'utilisation de méthodes spécifiques à l'ascendance telles que root? Et indirects. https://qiita.com/Rubyist_SOTA/items/49383aa7f60c42141871

Voir la création

app/views/categories/show.html.haml


.products-container
  .products-index
    .title
      = "#{@category.name}Liste de produits"
      .title__border
    - if @items
      %ul.lists
        = render "items/item", items: @items
    = paginate @items

Le modèle partiel utilisé sur toutes les pages de liste de produits est partagé. Le contenu affiché est modifié en fonction de la valeur de @items.

Créer des liens vers d'autres catégories

Enfin, ajoutez des liens vers d'autres catégories comme indiqué ci-dessous pour faciliter la recherche de produits. 4f5519ec96f8863baa48a2f49dd17281.png Si la catégorie d'affichage est parent ou enfant, créez un lien vers la catégorie un niveau ci-dessous, Pour les petits-enfants, affichez des liens vers les catégories de petits-enfants qui appartiennent à la même catégorie enfant.

app/controllers/categories_controller.rb


def set_category
  @category = Category.find(params[:id])
  #Postscript---------------------------------
  if @category.has_children?
    @category_links = @category.children
  else
    @category_links = @category.siblings
  end
  # -------------------------------------
end

app/views/categories/show.html.haml



//Postscript--------------------------------------------------
.category_wrapper
  .category_links
    - @category_links.each do |category|
      = link_to category.name, category_path(category)
// -----------------------------------------------------
.products-container
  .products-index
    .title
      = "#{@category.name}Liste de produits"
      .title__border
    - if @items
      %ul.lists
        = render "items/item", items: @items
    = paginate @items

Après cela, si vous organisez le CSS de manière appropriée, il sera terminé.

finalement

Ceci complète la fonction de recherche de produits à partir de catégories à plusieurs niveaux. Merci d'avoir lu jusqu'ici.

Recommended Posts

[Rails] Fonction de recherche et de liste de produits à partir de catégories à plusieurs niveaux
Implémentation de la fonction de recherche floue Rails
[Rails] Implémenter la fonction de recherche d'utilisateurs
Fonction de recherche à l'aide de [rails] ransack
[Rails] Recherche à partir de plusieurs colonnes + conditions avec Gem et ransack
Ajoutez une fonction de recherche dans Rails.
[Java] Conversion d'un tableau à une liste
Mode API Rails J'ai essayé d'implémenter la fonction de recherche multiple par mot-clé à l'aide de tableaux et d'un traitement itératif.
Fonction Strict_loading pour supprimer l'occurrence de problème N + 1 ajoutée à partir des rails 6.1
Enregistrement du tutoriel Rails et mémorandum n ° 1 "De l'installation au déploiement hello_app + gestion des erreurs"
De la traction des rails image-docker au lancement
[Ruby on Rails] Fonction de recherche (non sélectionnée)
Comment implémenter la fonctionnalité de recherche dans Rails
Installez Webpacker et Yarn pour exécuter Rails
[Rails] Comment convertir ERB en Haml
Rails Ajout d'une fonction de connexion facile et facile
[Rails] Assignation de variables du contrôleur à JavaScript
[Rails] [Note] Quand ajouter = à <%%> et quand pas
Utilisez Stream # collect pour récupérer et répertorier uniquement des champs spécifiques à partir d'une liste Java Bean