Ich heiße Kusano. Dieser Beitrag wird eine Ausgabe sein, nachdem ich überprüft habe, was ich an der Programmierschule gelernt habe. Der Text ist schlecht, weil er ein Memo für mich ist, aber ich hoffe, er wird Anfängern so viel wie möglich helfen. Wie der Titel schon sagt, handelt der Inhalt von der Implementierung der Kategoriefunktion der Furima-App durch Teamentwicklung an der Schule. Ich denke, es gibt viele unreife Punkte. Bitte weisen Sie auf Mängel hin. Ich werde es von Zeit zu Zeit verbessern.
Wenn die übergeordnete Kategorie ausgewählt ist, wird das Ereignis ausgelöst und die Felder für Kind, Enkel und Auswahl werden angezeigt.
** Kategorie-Registrierungsbildschirm bei der Auflistung von Produkten **
** Bildschirm mit Informationen zu Kategorieninformationen für detaillierte Produktinformationen **
** 1. Modell erstellen und Zuordnung in DB definieren **
--Installation der Edelstein-Abstammung --Erstellen eines Kategoriemodells --category Erstellung einer Migrationsdatei
** 2. Kategorieregistrierungsfunktion **
--Routing-Einstellungen für JSON in Kinder- und Enkelkategorien --Items Controller-Instanzvariablendefinition für übergeordnete Kategorie --items Controller-Methodendefinition für JSON von Kinder- und Enkelkategorien
** 3. Kategorieninformationen aufrufen **
Verwenden Sie das Juwel "Abstammung" von Ruby on Rails, um Kategoriefunktionen hinzuzufügen.
Gemfile
gem 'ancestry'
Erstellen Sie ein Kategoriemodell mit dem Befehl Rails g Model Category im Terminal. Beschreibe has_ancestory.
app/models/category.rb
class Category < ApplicationRecord
has_ancestry
has_many :items
end
Schreiben Sie Folgendes in die Migrationsdatei für Kategorien und führen Sie den Befehl Rails db: migrate im Terminal aus.
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
Beschreiben Sie alle Kategorien in der Google-Tabelle. Die A-Spalte ist id, die B-Spalte ist name (Kategoriename) und die C-Spalte ist Abstammung (numerischer Wert, der Eltern und Nachkommen unterscheidet). Ich habe alle Kategorien in eine CSV-Datei geschrieben, aber es gab 1368 Zeilen, daher fiel mir die Eingabe schwer. (Ich erinnere mich an die Büroarbeit, die ich in meinem vorherigen Job gemacht habe.) Übrigens gibt es eine Kategorie ohne Enkelkinder. Achten Sie also darauf, den Wert der Vorfahren nicht zu verschieben. Sie können die Daten speichern, indem Sie die Schritte Datei → Herunterladen → durch Kommas getrennte Werte (aktuelles CSV-Blatt) ausführen. Fügen Sie die heruntergeladene CSV-Datei direkt in die Datenbankdatei ein.
Schreiben Sie Folgendes in die Datei seeds.rb und führen Sie den Befehl Rails db: seed im Terminal aus, um die CSV-Datei zu lesen und automatisch einen DB-Datensatz zu generieren. Obwohl dies eine Erklärung zum Beschreibungsinhalt ist, geben Sie die Datei an, die Sie nach foreach 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] → C-Spalte ist Abstammung (numerischer Wert, der Eltern und Nachkommen unterscheidet)
db/seeds.rb
require "csv"
CSV.foreach('db/category.csv') do |row|
Category.create(:id => row[0], :name => row[1], :ancestry => row[2])
end
Routing-Einstellungen für JSON in Kategorien für Kinder und Enkelkinder Die beiden besten in der Sammlung sind die Routings für den diesmal erstellten JSON. Wenn Sie die Standardeinstellungen {fomat: 'json'} schreiben, gilt dies nur für JSON.
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
Definition der Instanzvariablen der übergeordneten Kategorie für den Elementcontroller Definieren Sie die folgende Beschreibung in der neuen Methode. (Im Verlauf der Implementierung wird es auch für andere Aktionen verwendet, sodass es später als privat neu definiert und mit before_action überarbeitet wird.)
app/controllers/items_controller.rb
@category_parent_array = Category.where(ancestry: nil)
Elemente Definition der Controller-Methode für JSON von Kinder- und Enkelkategorien Die Beschreibung in Klammern von params [] beschreibt: parent_id und: child_id, die von ajax in der später erläuterten JavaScript-Datei gesendet werden.
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
Erstellen Sie eine json.jbuilder-Datei und beschreiben Sie die Konvertierung in JSON-Daten.
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
Legen Sie das Verhalten bei der Auswahl eines Elternteils, Kindes oder Enkels mit JavaScript fest
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('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 != "" && 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('Die Kategorie konnte nicht abgerufen werden');
})
}else{
$('#grandchildren_wrapper').remove();
}
})
});
Ich werde die obige Beschreibung erklären. Das Ereignis wird ausgelöst, wenn im übergeordneten Auswahlfeld eine Kategorie ausgewählt wird, die zuerst in der folgenden Beschreibung in der mittleren Zeile angezeigt wird. Die Beschreibung in der zweiten Zeile erhält die ID der ausgewählten Kategorie und definiert die Variablen.
①
$('#item_category_id').on('change',function(){
var parentId = document.getElementById('item_category_id').value;
Fügen Sie als Nächstes die ID der von ajax in ① erfassten Kategorie in parent_id ein, übergeben Sie die parent_id über die zuvor geroutete Route für JSON an den Controller und erfassen Sie den Datensatz der untergeordneten Kategorie.
②
$.ajax({
url: '/items/get_category_children/',
type: 'GET',
data: { parent_id: parentId },
dataType: 'json'
})
Wenn die Ajax-Kommunikation erfolgreich ist, wird der Datensatz der in ② erfassten untergeordneten Kategorie in der 5. Zeile um die forEach-Methode erweitert. Die Entfernungsmethode in der 2. und 3. Zeile wurde geschrieben, um die Auswahlfelder für Kinder und Enkel zu entfernen, wenn im übergeordneten Auswahlfeld erneut eine andere Kategorie ausgewählt wird.
③
.done(function(children){
$('#children_wrapper').remove();
$('#grandchildren_wrapper').remove();
var insertHTML = '';
children.forEach(function(child){
insertHTML += appendOption(child);
});
appendChildrenBox(insertHTML);
})
Die in der oberen Zeile beschriebene appendOption übergibt den zuvor mit dem Argument appendOption (child) in der 6. Zeile von ③ erfassten untergeordneten Datensatz und bettet id und name (Kategoriename) in das Options-Tag ein.
④
function appendOption(category){
var html = `<option value="${category.id}">${category.name}</option>`;
return html;
}
Fügen Sie für appendChildrenBox den Inhalt von ④ in das in der 6. Zeile von ③ beschriebene insertHTML ein und übergeben Sie das Options-Tag von ④ in dem in der 8. Zeile von ③ beschriebenen Argument von appendChildrenBox (insertHTML). Betten Sie das Optionstag mit der Beschreibung von \ $ {insertHTML} ein. Schließlich die Beschreibung von $ ('.append__category'). Append (childSelectHtml); bewirkt, dass der Browser das untergeordnete Auswahlfeld asynchron anzeigt. Der Ablauf des Enkel-Auswahlfelds ist der gleiche.
⑤
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);
}
Wenn die Ajax-Kommunikation fehlschlägt, wird eine Warnung angezeigt.
⑥
.fail(function(){
alert('Die Kategorie konnte nicht abgerufen werden');
})
Für die oben beschriebene if-Anweisung ajax wird der Anfangswert mit der Option include_blank von collection_select in der haml-Datei auf nil gesetzt. Wenn die Option mit der ID von nil ausgewählt wird, beginnt die Ajax-Kommunikation. Im Gegenteil, wenn es auf den Anfangswert von "Bitte auswählen" zurückgesetzt wird, wird es zu "else" und das Auswahlfeld für Enkel wird gelöscht.
⑦
if (parentId != ""){
#Die Beschreibung in der Mitte wird weggelassen
}else{
$('#grandchildren_wrapper').remove();
In Bezug auf den Unterschied zwischen der Beschreibung des Kindes und der Beschreibung des Enkels muss die Beschreibung des Enkels wie folgt beschrieben werden, wenn die von JavaScript hinzugefügte Beschreibung für das Auslösen von Ereignissen vorgesehen ist. \ $ (Untersuchungsbereich) .on (Ereignisname, Ort, an dem das Ereignis auftritt, function () { Darüber hinaus wird die bedingte Verzweigung so festgelegt, dass die Ajax-Kommunikation beginnt, wenn die if-Anweisung nicht in der Kategorie ohne Enkelkinder enthalten ist.
⑧
$('.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){
Es gibt eine Einschränkung, wenn das Auswahlfeld asynchron im Browser angezeigt wird. Hier geht es um den Teil, in dem "item [category_id]" im Auswahl-Tag für Kinder und Enkelkinder mit der Option name festgelegt ist. Die Option name gibt an, welche Kategorie-ID von Eltern, Kindern oder Enkeln in der Elementtabelle gespeichert werden soll.
** Namensoption nur für Kinder hinzufügen und Enkelkategorie eingeben ** → In der DB wird die untergeordnete ID gespeichert ** Namensoption nur für Enkelkinder hinzufügen, Kategorie ohne Enkelkinder eingeben ** → In der Datenbank wird die übergeordnete Kategorie-ID gespeichert ** Fügen Sie eine Namensoption für Kinder und Enkelkinder hinzu und geben Sie bis zur Kategorie Enkelkinder ein ** → In der Datenbank wird das Auswahl-Tag mit der am Ende asynchron angezeigten Namensoption mit Priorität gespeichert.
Der Grund, warum die Kategorie-ID des Enkels gespeichert werden muss, besteht darin, dass die übergeordneten und untergeordneten Datensätze beim Aufrufen der Kategoriedaten basierend auf der Kategorie-ID des Enkels aufgerufen werden können.
⑨
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);
}
Zeigen Sie das übergeordnete Auswahlfeld in der Haml-Datei an.
rb:app/views/items/_form.html.haml
.append__category
.category
.form__label
.lavel__name
Kategorie
.lavel__Required
[Verpflichtend]
=f.collection_select :category_id, @category_parent_array, :id, :name,{ include_blank: "Bitte auswählen"},class:"serect_field"
Definieren Sie übergeordnete, untergeordnete und Enkelinstanzvariablen in der show-Methode des Elementcontrollers
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)
Rufen Sie die Kategorie, die mit der zuvor im Element-Controller definierten Instanzvariablen registriert wurde, in der Ansicht mit einer Haml-Datei auf. Die if-Anweisung ist abhängig von der Anzeige ohne Enkelkinder oder mit Enkelkindern. (Da der Pfad diesmal nicht für den Link angegeben ist, wird er als # festgelegt.)
rb:app/views/items/_main_show.html.haml
%table
%tr
%th Verkäufer
%td= @user.nickname
%tr
%th Kategorie
- 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
%th Marke
%td= @item.brand_name
%tr
%th Produktgröße
%td
%tr
%th Produktstatus
%td= @item.item_status
%tr
%th Versandkosten
%td= @item.delivery_fee
%tr
%Versandbereich
%td= link_to "#{@item.shipping_origin}","#"
%tr
%Voraussichtliches Versanddatum
%td= @item.days_until_shipping
Realisieren Sie das Auswahlfeld für dynamische Kategorien mithilfe mehrschichtiger Daten nach Herkunft ~ Ajax ~ [Übersetzung] Gem Ancestry Official Document
Recommended Posts