Ho un pannello attivo con una selezione dipendente, vale a dire la scelta sul primo menu a discesa impatta ciò che appare nel secondo menu a discesa.Rails 4 - caricamento ingombrante su selezione dipendente che causa errore (Rails4/Active Admin)
Tutto funzionava perfettamente bene qualche mese fa ma ho appena realizzato ieri che non funziona più.
Sono riuscito a trovare la causa dell'errore: se rimuovo il caricamento di eager ("include"), quindi funziona di nuovo.
NON LAVORO: (versione attuale):
@deal_subsectors = DealSector.find(params[:deal_sector_id],
include: :deal_subsectors).dealsubsectors
ottengo questo errore (console strumenti forma cromo dev)
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
LAVORO, quando rimuovo "include"/carico desideroso:
@deal_subsectors = DealSector.find(params[:deal_sector_id]).deal_subsectors
Funziona perfettamente in quel caso.
Ma voglio davvero caricare i sottosettori delle transazioni, quindi mi chiedo che cosa stia causando questo errore, cosa è cambiato da quando funzionava. Ho alcune supposizioni ma non riesco a trovare il colpevole.
Forse Rails 4 cambiamento del modo in cui dovrei usare find (params [: id] ..), o il modo in cui dovrei usare eager loading
ha cambiato Admin attiva il modo in cui gestisce eager loading: forse funziona solo su indice e non su pagine di modifica ...
ha fatto i turbolinks ora su Rails 4 cambiare il modo in cui devo caricare carico?
Ecco il codice:
- su Admin attivo
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
- il modulo con le 2 seleziona dipendenti
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
- il javascript alimentandolo:
// 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
};
file aggiunto
class DealSector < ActiveRecord::Base
has_many :deal_subsectors
end
class DealSubsector < ActiveRecord::Base
belongs_to :deal_sector, :foreign_key => 'deal_sector_id'
end
sembra funzionare. solo una domanda: è normale che la velocità di caricamento che posso vedere nel mio terminale sia più alta con @deal_subsectors = DealSector.eager_load (: deal_subsectors) .find (params [: deal_sector_id]). deal_subsectors di quando non faccio MAI carico (@deal_subsectors = DealSector.find (params [: deal_sector_id]). deal_subsectors? Dato che non ho molti sottosettori (come meno di 20 al momento), forse è normale che il carico di lavoro richiede più tempo che senza carico eccessivo. giusto dire che il carico di lavoro pagherà quando avrò molti altri sottosettori? – Mathieu
Sì @mathieu i tuoi pensieri sono assolutamente corretti. Il più delle volte il caricamento impaziente ti tiene lontano dalla trappola di query N + 1, senza il carico impaziente potresti essere eseguendo 100 query per ottenere 1 risultato invece di eseguire 1 query per ottenere 100 risultati. Il caricamento ansioso ripagherà sempre, potrebbe essere possibile ottenere una o due eccezioni. Nel tuo caso, il caricamento rapido ridurrà definitivamente il tempo di interrogazione e renderà la tua risposta veloce. più grande no dei dati avrai più benefici che ottieni dal caricamento avido. – meOn
tx per ulteriori chiarimenti – Mathieu