Mon nom est Kusano. Ce message sera une sortie après avoir examiné ce que j'ai appris à l'école de programmation. Le texte est médiocre car c'est une note pour moi, mais j'espère qu'il aidera autant que possible les débutants. Comme le titre l'indique, le contenu porte sur la mise en œuvre de la fonction de catégorie de l'application Furima par le développement d'équipe mené à l'école. Je pense qu'il y a de nombreux points immatures. Veuillez signaler toute lacune. Je vais l'améliorer de temps en temps.
Lorsque la catégorie parent est sélectionnée, l'événement se déclenche et les cases enfant, petit-enfant et sélection s'affichent.
** Écran d'enregistrement de catégorie lors de la liste des produits **
** Écran d'appel d'informations sur la catégorie pour des informations détaillées sur le produit **
** 1. Création d'un modèle et définition d'une association dans DB **
--Installation de l'ascendance des gemmes --Création d'un modèle de catégorie --category Création du fichier de migration --Définition d'association avec le modèle d'élément
** 2. Fonction d'enregistrement de catégorie **
** 3. Informations sur la catégorie d'appel **
--Définissez les variables d'instance parent, enfant et petit-enfant dans la méthode show du contrôleur d'éléments --items Décrit dans un fichier haml à l'aide de la variable d'instance définie dans le contrôleur et appelée dans la vue
Utilisez la gemme «ascendance» de Ruby on Rails pour ajouter des fonctionnalités de catégorie.
Gemfile
gem 'ancestry'
Créez un modèle de catégorie avec la commande rails g model category dans le terminal. Décrivez has_ancestory.
app/models/category.rb
class Category < ApplicationRecord
has_ancestry
has_many :items
end
Écrivez ce qui suit dans le fichier de migration des catégories et exécutez la commande rails db: migrate dans le terminal.
db/category.rb
class CreateCategories < ActiveRecord::Migration[5.2]
def change
create_table :categories do |t|
t.string :name, null: false
t.string :ancestry
t.timestamps
end
add_index :categories, :ancestry
end
end
Décrivez toutes les catégories sur la feuille de calcul Google. La colonne A est id, la colonne B est le nom (nom de la catégorie) et la colonne C est l'ascendance (valeur numérique qui distingue les parents et les descendants). J'ai écrit toutes les catégories dans un fichier CSV, mais il y avait 1368 lignes, donc j'ai eu du mal à entrer. (Je me souviens du travail de bureau que je faisais dans mon emploi précédent.) Soit dit en passant, il existe une catégorie sans petits-enfants, alors faites attention à ne pas modifier la valeur de l'ascendance. Vous pouvez enregistrer les données en suivant les étapes de Fichier → Télécharger → valeurs séparées par des virgules (feuille actuelle .csv). Placez le fichier CSV téléchargé directement dans le fichier db.
Écrivez ce qui suit dans le fichier seeds.rb et exécutez la commande rails db: seed dans le terminal pour lire le fichier CSV et générer automatiquement un enregistrement DB. Bien qu'il s'agisse d'une explication sur le contenu de la description, spécifiez le fichier que vous souhaitez lire après foreach. La description ci-dessous sera le nom du modèle.create (nom de la colonne => colonne que vous souhaitez charger). row [0] → Une colonne est id ligne [1] → la colonne B est le nom (nom de la catégorie) ligne [2] → la colonne C est l'ascendance (valeur numérique qui distingue les parents et les descendants)
db/seeds.rb
require "csv"
CSV.foreach('db/category.csv') do |row|
Category.create(:id => row[0], :name => row[1], :ancestry => row[2])
end
Paramètres de routage pour JSON dans les catégories enfants et petits-enfants Les deux premiers de la collection sont les routages pour le JSON créé cette fois. En écrivant les valeurs par défaut: {fomat: 'json'}, ce sera pour JSON uniquement.
config/routes.rb
resources :items do
resources :comments, only: [:create, :destroy]
resources :favorites, only: [:create, :destroy]
collection do
get 'get_category_children', defaults: { fomat: 'json'}
get 'get_category_grandchildren', defaults: { fomat: 'json'}
get 'search'
get 'post_done'
get 'delete_done'
get 'detail_search'
get 'update_done'
end
end
Définition de variable d'instance de catégorie parente pour le contrôleur d'éléments Définissez la description suivante dans la nouvelle méthode. (Au fur et à mesure que l'implémentation progresse, elle sera également utilisée pour d'autres actions, elle sera donc redéfinie comme privée plus tard et refactorisée avec before_action.)
app/controllers/items_controller.rb
@category_parent_array = Category.where(ancestry: nil)
Éléments Définition de la méthode du contrôleur pour JSON des catégories enfants et petits-enfants La description entre parenthèses de params [] décrit: parent_id et: child_id envoyés par ajax dans le fichier JavaScript expliqué plus loin.
app/controllers/items_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
Créez un fichier json.jbuilder et décrivez la conversion en données JSON.
rb:app/views/items/get_category_children.json.jbuilder
json.array! @category_children do |child|
json.id child.id
json.name child.name
end
rb:app/views/items/get_category_grandchildren.json.jbuilder
json.array! @category_grandchildren do |grandchild|
json.id grandchild.id
json.name grandchild.name
end
Définissez le comportement lors de la sélection d'un parent, d'un enfant ou d'un petit-enfant avec JavaScript
app/assets/javascripts/category.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="item[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="item[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: '/items/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);
})
.fail(function(){
alert('Échec de l'obtention de la catégorie');
})
}else{
$('#children_wrapper').remove();
$('#grandchildren_wrapper').remove();
}
});
$('.append__category').on('change','#child__category',function(){
var childId = document.getElementById('child__category').value;
if(childId != "" && childId != 46 && childId != 74 && childId != 134 && childId != 142 && childId != 147 && childId != 150 && childId != 158){
$.ajax({
url: '/items/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);
})
.fail(function(){
alert('Échec de l'obtention de la catégorie');
})
}else{
$('#grandchildren_wrapper').remove();
}
})
});
Je vais expliquer la description ci-dessus. L'événement est défini pour se déclencher lorsqu'une catégorie est sélectionnée dans la zone de sélection parent qui s'affiche en premier dans la description suivante sur la ligne du milieu. La description sur la deuxième ligne obtient l'identifiant de la catégorie sélectionnée et définit les variables.
①
$('#item_category_id').on('change',function(){
var parentId = document.getElementById('item_category_id').value;
Ensuite, placez l'id de la catégorie acquise dans ① par ajax dans parent_id, transmettez l'id parent_id au contrôleur via la route pour JSON acheminée plus tôt et acquérez l'enregistrement de la catégorie enfant.
②
$.ajax({
url: '/items/get_category_children/',
type: 'GET',
data: { parent_id: parentId },
dataType: 'json'
})
Si la communication ajax réussit, l'enregistrement de catégorie enfant acquis dans (2) est développé par la méthode forEach sur la 5ème ligne. La méthode remove sur les 2ème et 3ème lignes est écrite pour supprimer les cases de sélection enfant et petit-enfant lorsqu'une autre catégorie est à nouveau sélectionnée dans la case de sélection parent.
③
.done(function(children){
$('#children_wrapper').remove();
$('#grandchildren_wrapper').remove();
var insertHTML = '';
children.forEach(function(child){
insertHTML += appendOption(child);
});
appendChildrenBox(insertHTML);
})
La fonction appendOption décrite dans la ligne supérieure transmet l'enregistrement enfant acquis précédemment avec l'argument de appendOption (enfant) sur la 6ème ligne de ③, et incorpore respectivement id et nom (nom de catégorie) dans la balise option.
④
function appendOption(category){
var html = `<option value="${category.id}">${category.name}</option>`;
return html;
}
Pour appendChildrenBox, le contenu de ④ est placé dans le insertHTML décrit dans la 6ème ligne de ③, et la balise option de ④ est passée comme argument de appendChildrenBox (insertHTML) décrit dans la 8ème ligne de ③. Incorporez la balise option avec la description de \ $ {insertHTML} Enfin, la description de $ ('.append__category'). Append (childSelectHtml); amène le navigateur à afficher la boîte de sélection enfant de manière asynchrone. Le déroulement de la boîte de sélection du petit-fils est le même.
⑤
function appendChildrenBox(insertHTML){
var childSelectHtml = "";
childSelectHtml = `<div class="category__child" id="children_wrapper">
<select id="child__category" name="item[category_id]" class="serect_field">
<option value="">---</option>
${insertHTML}
</select>
</div>`;
$('.append__category').append(childSelectHtml);
}
Si la communication ajax échoue, une alerte sera affichée.
⑥
.fail(function(){
alert('Échec de l'obtention de la catégorie');
})
Pour l'instruction if décrite ci-dessus ajax, la valeur initiale est définie sur nil en utilisant l'option include_blank de collection_select dans le fichier haml, et lorsque cela sélectionne l'option avec id à partir de nil, la communication ajax démarre. Au contraire, lorsqu'il est renvoyé à la valeur initiale de "Veuillez sélectionner", il devient else et la boîte de sélection du petit-enfant est supprimée.
⑦
if (parentId != ""){
#La description au milieu est omise
}else{
$('#grandchildren_wrapper').remove();
En ce qui concerne la différence entre la description de l'enfant et la description du petit-enfant, la description du petit-enfant doit être décrite comme suit lorsque celle ajoutée par javaScript est ciblée pour le déclenchement d'événement. \ $ (Étendue de l'enquête) .on (nom de l'événement, lieu où l'événement se produit, function () { De plus, le branchement conditionnel est défini de sorte que la communication ajax démarre lorsque l'instruction if n'est pas dans la catégorie sans petits-enfants.
⑧
$('.append__category').on('change','#child__category',function(){
var childId = document.getElementById('child__category').value;
if(childId != "" && childId != 46 && childId != 74 && childId != 134 && childId != 142 && childId != 147 && childId != 150 && childId != 158){
Il y a une mise en garde lors de l'affichage de la zone de sélection de manière asynchrone sur le navigateur. Il s'agit de la partie où les enfants et les petits-enfants ont "item [category_id]" dans l'option de nom dans la balise select. L'option name spécifie quel category_id du parent, de l'enfant ou du petit-enfant doit être stocké dans la table des éléments.
** Ajouter l'option de nom uniquement aux enfants et entrer dans la catégorie des petits-enfants ** → Dans DB, l'ID enfant est enregistré ** Ajouter l'option de nom uniquement aux petits-enfants, entrez la catégorie sans petits-enfants ** → Dans DB, l'id category_id parent est sauvegardé ** Ajouter une option de nom pour les enfants et petits-enfants, et entrer jusqu'à la catégorie petits-enfants ** → Dans DB, la variable de sélection avec l'option de nom affichée de manière asynchrone à la fin est enregistrée avec priorité.
La raison pour laquelle il est nécessaire de sauvegarder le category_id du petit-enfant est que les enregistrements parent et enfant peuvent être appelés en fonction du category_id du petit-enfant lors de l'appel des informations de catégorie.
⑨
function appendChildrenBox(insertHTML){
var childSelectHtml = "";
childSelectHtml = `<div class="category__child" id="children_wrapper">
<select id="child__category" name="item[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="item[category_id]" class="serect_field">
<option value="">---</option>
${insertHTML}
</select>
</div>`;
$('.append__category').append(grandchildSelectHtml);
}
Affichez la boîte de sélection parent dans le fichier haml.
rb:app/views/items/_form.html.haml
.append__category
.category
.form__label
.lavel__name
Catégorie
.lavel__Required
[Obligatoire]
=f.collection_select :category_id, @category_parent_array, :id, :name,{ include_blank: "Veuillez sélectionner"},class:"serect_field"
Définissez les variables d'instance parent, enfant et petit-enfant dans la méthode show du contrôleur d'éléments
app/controllers/items_controller.rb
@category_id = @item.category_id
@category_parent = Category.find(@category_id).parent.parent
@category_child = Category.find(@category_id).parent
@category_grandchild = Category.find(@category_id)
Appelez la catégorie enregistrée à l'aide de la variable d'instance définie précédemment dans le contrôleur d'éléments à la vue avec un fichier haml. L'instruction if est conditionnelle à l'affichage sans petits-enfants ou avec petits-enfants. (Puisque le chemin n'est pas spécifié pour le lien cette fois, il est défini sur #.)
rb:app/views/items/_main_show.html.haml
%table
%tr
%e vendeur
%td= @user.nickname
%tr
%catégorie
- if [46, 74, 134, 142, 147, 150, 158].include?(@category_id)
%td
= link_to "#{@category_child.name}","#"
%br= link_to "#{@category_grandchild.name}","#"
-else
%td
= link_to "#{@category_parent.name}","#"
%br= link_to "#{@category_child.name}","#"
= link_to "#{@category_grandchild.name}","#"
%tr
%e marque
%td= @item.brand_name
%tr
%taille du produit
%td
%tr
%Statut du produit
%td= @item.item_status
%tr
%e Frais d'expédition
%td= @item.delivery_fee
%tr
%e Zone d'expédition
%td= link_to "#{@item.shipping_origin}","#"
%tr
%Date d'expédition estimée
%td= @item.days_until_shipping
Réalisez une boîte de sélection de catégorie dynamique en utilisant des données multicouches par ascendance ~ Ajax ~ [Français] Gem Ancestry Official Document
Recommended Posts