・ Ruby: 2.5.7 Schienen: 5.2.4 ・ Vagrant: 2.2.7 -VirtualBox: 6.1 ・ Betriebssystem: macOS Catalina
Folgendes wurde implementiert.
・ Schlanke Einführung ・ Einführung von Bootstrap 3 ・ Einführung von Font Awesome
category.rb
category.rb
def self.category_parent_array_create
category_parent_array = ['---']
Category.where(ancestry: nil).each do |parent|
category_parent_array << [parent.name, parent.id]
end
return category_parent_array
end
category_parent_array = ['---']
Category.where(ancestry: nil).each do |parent|
category_parent_array << [parent.name, parent.id]
end
** * Wichtige Punkte **
[parent.name, parent.id]
➡︎ Bei Anzeige der übergeordneten Kategorie im Auswahlfeld in der Ansicht
Das erste Argument (parent.name) wird zum Wert, der im Browser angezeigt wird.
Das zweite Argument (parent.id) ist der Wert, der als Parameter gesendet werden soll.
①
erstellte Array als Rückgabewert zurück.return category_parent_array
book_category.rb
def self.maltilevel_category_create(book, parent_id, children_id, grandchildren_id)
if parent_id.present? && parent_id != '---'
category = Category.find(parent_id)
BookCategory.create(book_id: book.id, category_id: category.id)
end
if children_id.present? && children_id != '---'
category = Category.find(children_id)
BookCategory.create(book_id: book.id, category_id: category.id)
end
if grandchildren_id.present? && grandchildren_id != '---'
category = Category.find(grandchildren_id)
BookCategory.create(book_id: book.id, category_id: category.id)
end
end
(book, parent_id, children_id, grandchildren_id)
book
: Daten des zu erstellenden Buches
parent_id
: ID der übergeordneten Kategorie
children_id
: ID der untergeordneten Kategorie
Enkelkinder_ID
: ID der Enkelkategorie
if parent_id.present? && parent_id != '---'
category = Category.find(parent_id)
BookCategory.create(book_id: book.id, category_id: category.id)
books_controller.rb
def create
@book = Book.new(book_params)
@book.user_id = current_user.id
if @book.save
BookCategory.maltilevel_category_create(
@book,
params[:parent_id],
params[:children_id],
params[:grandchildren_id]
)
redirect_to books_path
else
@books = Book.all
@category_parent_array = Category.category_parent_array_create
render 'index'
end
end
def index
@book = Book.new
@books = Book.all
@category_parent_array = Category.category_parent_array_create
end
def get_category_children
@category_children = Category.find(params[:parent_id]).children
end
def get_category_grandchildren
@category_grandchildren = Category.find(params[:children_id]).children
end
maltilevel_category_create
und führen Sie sie aus.BookCategory.maltilevel_category_create(
@book,
params[:parent_id],
params[:children_id],
params[:grandchildren_id]
)
** ◎ Empfangen Sie die von der Ajax-Kommunikation gesendeten Parameter. ** ** **
params[:parent_id],
params[:children_id],
params[:grandchildren_id]
@category_parent_array = Category.category_parent_array_create
def get_category_children
@category_children = Category.find(params[:parent_id]).children
end
def get_category_grandchildren
@category_grandchildren = Category.find(params[:children_id]).children
end
Terminal
$ touch app/views/books/get_category_children.json.jbuilder
ruby:books/get_category_children.json.jbuilder
json.array! @category_children do |children|
json.id children.id
json.name children.name
end
Terminal
$ touch app/views/books/get_category_grandchildren.json.jbuilder
ruby:books/get_category_grandchildren.json.jbuilder
json.array! @category_grandchildren do |grandchildren|
json.id grandchildren.id
json.name grandchildren.name
end
get_category_children
extrahierten Datensätze, um ein Array zu erstellen.json.array! @category_children do |children|
①
erstellten Array.json.id children.id
json.name children.name
** ◎ Rückgabewert bei Auswahl der übergeordneten Kategorie (Unternehmen) **
[
{
"id": 2,
"name": "Finanzen"
},
{
"id": 6,
"name": "Wirtschaft"
},
{
"id": 9,
"name": "Management"
},
{
"id": 13,
"name": "Marketing"
},
]
** ◎ Wenn die untergeordnete Kategorie (Finanzen) ausgewählt ist **
[
{
"id": 3,
"name": "Lager"
},
{
"id": 4,
"name": "Austausch-"
},
{
"id": 5,
"name": "MwSt"
},
]
routes.rb
#Nachtrag
get 'get_category/children', to: 'books#get_category_children', defaults: { format: 'json' }
get 'get_category/grandchildren', to: 'books#get_category_grandchildren', defaults: { format: 'json' }
slim:books/index.html.slim
.category-form
= label_tag 'Genre'
= select_tag 'parent_id', options_for_select(@category_parent_array), id: 'parent-category', class: 'form-control'
i.fas.fa-chevron-down
br
= select_tag 'parent_id', options_for_select(@category_parent_array), id: 'parent-category', class: 'form-control'
Terminal
$ touch app/assets/javascripts/category_form.js
category_form.js
$(function() {
function appendOption(category) {
let html = `<option value='${category.id}' data-category='${category.id}'>${category.name}</option>`;
return html;
}
function appendChidrenBox(insertHTML) {
let childrenSelectHtml = '';
childrenSelectHtml = `
<div id='children-wrapper'>
<select id='children-category' class='form-control' name='[children_id]'>
<option value='---' data-category='---'>---</option>
${insertHTML}
</select>
<i class='fas fa-chevron-down'></i>
</div>
`;
$('.category-form').append(childrenSelectHtml);
}
function appendGrandchidrenBox(insertHTML) {
let grandchildrenSelectHtml = '';
grandchildrenSelectHtml = `
<div id='grandchildren-wrapper'>
<select id='grandchildren-category' class='form-control' name='[grandchildren_id]'>
<option value='---' data-category='---'>---</option>
${insertHTML}
</select>
<i class='fas fa-chevron-down'></i>
</div>
`;
$('.category-form').append(grandchildrenSelectHtml);
}
$('#parent-category').on('change', function() {
let parentId = document.getElementById('parent-category').value;
if (parentId != '---') {
$.ajax({
url: '/get_category/children',
type: 'GET',
data: {
parent_id: parentId,
},
dataType: 'json',
})
.done(function(children) {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
let insertHTML = '';
children.forEach(function(children) {
insertHTML += appendOption(children);
});
appendChidrenBox(insertHTML);
})
.fail(function() {
alert('Das Genre konnte nicht verstanden werden');
});
} else {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
}
});
$('.category-form').on('change', '#children-category', function() {
let childrenId = $('#children-category option:selected').data('category');
if (childrenId != '---') {
$.ajax({
url: '/get_category/grandchildren',
type: 'GET',
data: {
children_id: childrenId,
},
dataType: 'json',
})
.done(function(grandchildren) {
if (grandchildren.length != 0) {
$('#grandchildren-wrapper').remove();
let insertHTML = '';
grandchildren.forEach(function(grandchildren) {
insertHTML += appendOption(grandchildren);
});
appendGrandchidrenBox(insertHTML);
}
})
.fail(function() {
alert('Das Genre konnte nicht verstanden werden');
});
} else {
$('#grandchildren-wrapper').remove();
}
});
});
$(function() {
function appendOption(category) {
let html = `<option value='${category.id}' data-category='${category.id}'>${category.name}</option>`;
return html;
}
** ◎ Legen Sie den Wert fest, der als Parameter gesendet werden soll. ** ** **
<option value='${category.id}' data-category='${category.id}'>
** * Wichtige Punkte **
Es entspricht dem Parameter, der von ①
von 3. Edit controller
empfangen wird.
** ◎ Legen Sie den Wert fest, der im Auswahlfeld angezeigt werden soll. ** ** **
${category.name}
function appendChidrenBox(insertHTML) {
let childrenSelectHtml = '';
childrenSelectHtml = `
<div id='children-wrapper'>
<select id='children-category' class='form-control' name='[children_id]'>
<option value='---' data-category='---'>---</option>
${insertHTML}
</select>
<i class='fas fa-chevron-down'></i>
</div>
`;
$('.category-form').append(childrenSelectHtml);
}
** ◎ Legen Sie den Parameternamen
des in ①
erstellten Parameters fest. ** ** **
name='[children_id]
** ◎ Erstellen Sie ein Auswahlfeld für untergeordnete Kategorien basierend auf den in ①
festgelegten Optionen. ** ** **
${insertHTML}
** ◎ Zeigen Sie das Auswahlfeld der untergeordneten Kategorie an. ** ** **
$('.category-form').append(childrenSelectHtml);
function appendGrandchidrenBox(insertHTML) {
let grandchildrenSelectHtml = '';
grandchildrenSelectHtml = `
<div id='grandchildren-wrapper'>
<select id='grandchildren-category' class='form-control' name='[grandchildren_id]'>
<option value='---' data-category='---'>---</option>
${insertHTML}
</select>
<i class='fas fa-chevron-down'></i>
</div>
`;
$('.category-form').append(grandchildrenSelectHtml);
}
$('#parent-category').on('change', function() {
let parentId = document.getElementById('parent-category').value;
if (parentId != '---') {
$.ajax({
url: '/get_category/children',
type: 'GET',
data: {
parent_id: parentId,
},
dataType: 'json',
})
.done(function(children) {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
let insertHTML = '';
children.forEach(function(children) {
insertHTML += appendOption(children);
});
appendChidrenBox(insertHTML);
})
.fail(function() {
alert('Das Genre konnte nicht verstanden werden');
});
} else {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
}
});
** ◎ Wird ausgelöst, wenn die übergeordnete Kategorie ausgewählt ist. ** ** **
$('#parent-category').on('change', function() {});
** ◎ Holen Sie sich die ID der ausgewählten übergeordneten Kategorie und weisen Sie sie der Variablen zu. ** ** **
let parentId = document.getElementById('parent-category').value;
** ◎ Wenn die übergeordnete Kategorie nicht der Standardwert ist Legen Sie die ID der übergeordneten Kategorie fest, die Sie zuvor im Parameter (parent_id) erhalten haben. Führen Sie die Aktion "get_category_children" asynchron aus. ** ** **
if (parentId != '---') {
$.ajax({
url: '/get_category/children',
type: 'GET',
data: {
parent_id: parentId,
},
dataType: 'json',
})
** ◎ Wenn die Ajax-Kommunikation erfolgreich ist, erstellen Sie ein Auswahlfeld für die untergeordnete Kategorie. Wenn die übergeordnete Kategorie geändert wird, während die Auswahlfelder unter der untergeordneten Kategorie bereits angezeigt werden, Löschen Sie die Auswahlfelder unter der untergeordneten Kategorie und erstellen Sie die Auswahlfelder für die untergeordneten Kategorien neu. ** ** **
.done(function(children) {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
let insertHTML = '';
children.forEach(function(children) {
insertHTML += appendOption(children);
});
appendChidrenBox(insertHTML);
})
** ◎ Wenn die asynchrone Kommunikation fehlschlägt, wird eine Warnung angezeigt. ** ** **
.fail(function() {
alert('Das Genre konnte nicht verstanden werden');
});
** ◎ Wenn die übergeordnete Kategorie der Anfangswert ist, löschen Sie die untergeordnete Kategorie und darunter. ** ** **
} else {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
}
$('.category-form').on('change', '#children-category', function() {
let childrenId = $('#children-category option:selected').data('category');
if (childrenId != '---') {
$.ajax({
url: '/get_category/grandchildren',
type: 'GET',
data: {
children_id: childrenId,
},
dataType: 'json',
})
.done(function(grandchildren) {
if (grandchildren.length != 0) {
$('#grandchildren-wrapper').remove();
let insertHTML = '';
grandchildren.forEach(function(grandchildren) {
insertHTML += appendOption(grandchildren);
});
appendGrandchidrenBox(insertHTML);
}
})
.fail(function() {
alert('Das Genre konnte nicht verstanden werden');
});
} else {
$('#grandchildren-wrapper').remove();
}
});
** ◎ Einige Kategorien haben keine Enkelkategorien, daher werden Bedingungen angegeben. (Fügen Sie nach Bedarf Bedingungen zu untergeordneten Kategorien hinzu.) **
if (grandchildren.length != 0)
Wenn Sie "Turbolinks" nicht deaktivieren, funktioniert das Auswahlfeld nicht asynchron. Deaktivieren Sie es daher unbedingt.
So deaktivieren Sie Turbolinks
Implementierung einer mehrschichtigen Kategoriefunktion (Formular bearbeiten)
Recommended Posts