Ich habe ein aktives Panel mit einer abhängigen Auswahl, d. H. Die Wahl auf der ersten Dropdown-Auswahl wirkt sich auf das, was in der zweiten Dropdown-Liste.Rails 4 - eifrig laden auf abhängige Auswahl verursacht Fehler (Rails4/Active Admin)
Alles funktionierte vor ein paar Monaten perfekt, aber ich habe erst gestern festgestellt, dass es nicht mehr funktioniert.
Ich habe es geschafft, zu finden, was den Fehler verursacht: Wenn ich die Eager loading entfernen ("include"), dann funktioniert es wieder.
FUNKTIONIERT NICHT: (aktuelle Version):
@deal_subsectors = DealSector.find(params[:deal_sector_id],
include: :deal_subsectors).dealsubsectors
ich diesen Fehler (Form Chrom Entwickler-Tools-Konsole)
GET http://localhost:3000/admin/deals/deal_subsectors_by_deal_sector?deal_sector_id=2 404 (Not Found)
send @ jquery.js?body=1:9660
jQuery.extend.ajax @ jquery.js?body=1:9211
jQuery.(anonymous function) @ jquery.js?body=1:9357
jQuery.extend.getJSON @ jquery.js?body=1:9340
update_deal_subsector @ active_admin.js?body=1:19
(anonymous function) @ active_admin.js?body=1:12
jQuery.event.dispatch @ jquery.js?body=1:4666
elemData.handle @ jquery.js?body=1:4334
ListPicker._handleMouseUp @ about:blank:632
WORKING, wenn ich entfernen "include"/eifriges Laden:
@deal_subsectors = DealSector.find(params[:deal_sector_id]).deal_subsectors
Es funktioniert perfekt in diesem Fall.
Aber ich möchte wirklich gerne Subsektoren laden, so frage ich mich, was diesen Fehler verursacht, was hat sich seit seiner Arbeit geändert. Ich habe ein paar Annahmen, aber ich kann den Schuldigen nicht finden.
Did Rails 4 Änderung der Art und Weise finde ich verwenden sollte (params [: id] ..) oder die Art, wie ich eifrig Laden
hat aktiv Admin die Art und Weise behandelt sie eifrig Laden verwenden sollten: vielleicht funktioniert es nur auf Index- und nicht auf Bearbeitungsseiten ...
hat turbolinks jetzt auf Rails 4 den Weg geändert, den ich eifrig laden muss?
Hier ist der Code:
- Active Admin
ActiveAdmin.register Deal do
# controller for the multi-select sector/subsector in the form
# does 2 things at same time: creates method and automatically defines the route of the method defined in controller
if params[:deal_sector_id] # pass the id
@deal_subsectors = DealSector.find(params[:deal_sector_id], include: :deal_subsectors).dealsubsectors
else
@deal_subsectors = []
end
render json: @deal_subsectors
end
end
- das Formular mit den 2-abhängigen wählt
form do |f|
f.inputs "Client" do
f.input :deal_sector_id,
:label => "Select industry:",
:as => :select,
:prompt => true,
:collection => DealSector.order("name").all.to_a
f.input :deal_subsector_id,
:label => "Select subindustry:",
:as => :select,
:prompt => true,
:collection => DealSubsector.order("name").all.to_a
end
end
- das JavaScript einschalten:
// for edit page
var deal_subsector = { };
$(document).ready(function() {
$('#deal_deal_sector_id').change(function() {
update_deal_subsector();
});
});
function update_deal_subsector() {
deal_sector_id = $('#deal_deal_sector_id').val(); //get the value of sector id
url = '/admin/deals/deal_subsectors_by_deal_sector?deal_sector_id=' + deal_sector_id; //make a query to the url passing the deal sector id as a parameter
$.getJSON(url, function(deal_subsectors) {
console.log(deal_subsectors);
$('#deal_deal_subsector_id').html("") //just blanks the id, blank it before populating it again if sector changes
for(i = 0; i < deal_subsectors.length; i++) {
console.log(deal_subsectors[i]);
$('#deal_deal_subsector_id').append("<option value=" + deal_subsectors[i].id + ">" + deal_subsectors[i].name + "</option>")
};
}); //pass the url and function to get subsector ids and all we get is assigned to the variable subsector_id
};
// for index page (filters)
$(document).ready(function() {
$('#q_deal_sector_id').change(function() {
update_deal_subsector_filter();
});
});
function update_deal_subsector_filter() {
deal_sector_id = $('#q_deal_sector_id').val(); //get the value of sector id
url = '/admin/deals/deal_subsectors_by_deal_sector?deal_sector_id=' + deal_sector_id; //make a query to the url passing the deal sector id as a parameter
$.getJSON(url, function(deal_subsectors) {
console.log(deal_subsectors);
$('#q_deal_subsector_id').html("") //just blanks the id, blank it before populating it again if sector changes
for(i = 0; i < deal_subsectors.length; i++) {
console.log(deal_subsectors[i]);
$('#q_deal_subsector_id').append("<option value=" + deal_subsectors[i].id + ">" + deal_subsectors[i].name + "</option>")
};
}); //pass the url and function to get subsector ids and all we get is assigned to the variable subsector_id
};
hinzugefügte Datei
class DealSector < ActiveRecord::Base
has_many :deal_subsectors
end
class DealSubsector < ActiveRecord::Base
belongs_to :deal_sector, :foreign_key => 'deal_sector_id'
end
scheint zu funktionieren. nur eine Frage: ist es normal, dass die Ladegeschwindigkeit, die ich in meinem Terminal sehen kann, höher ist mit @deal_subsectors = DealSector.ager_load (: deal_subsectors) .find (params [: deal_sector_id]). deal_subsectors als wenn ich KEINE eifrigen Ladevorgang mache (@deal_subsectors = DealSector.find (params [: deal_sector_id]). deal_subsectors? Da ich nicht viele Untersektoren habe (im Moment weniger als 20), ist es vielleicht normal, dass das E-Laden länger dauert als ohne E-Laden Recht zu sagen, es eifrig wird sich auszahlen, wenn ich noch viele Subsektoren haben werde? – Mathieu
Ja @mathieu Ihre Gedanken sind absolut richtig Die meiste Zeit eifrig Laden halten Sie von der N + 1 Abfrage Trap, ohne eifrig laden können Sie sein 100 Abfrage ausführen, um 1 Ergebnis zu erhalten, anstatt 1 Abfrage zu laufen, um 100 Ergebnisse zu erhalten.Egis Laden wird immer auszahlen, möglicherweise können Sie eine oder zwei Ausnahmen erhalten .. In Ihrem Fall eifrigloading definitiv reduzieren Sie die Abfrage Zeit und machen yo Deine Antwort schnell. größere Nr. von Daten haben Sie mehr Nutzen, den Sie vom eifrigen Laden bekommen. – meOn
Tx für Ihre weiteren Erklärungen – Mathieu