Bonjour voilà je vous expose mon problème, actuellement développant une application de calcul de subvention, je dois recuperer les villes les départements associé aux villes ainsi que les régions.
A savoir que pour chaque ville departements et régions des subventions sont attribués.
Mon probléme est que en stockant dans la bdd toutes les villes cela est très lourd est donc ralenti considérablement mon application lors de la connection de l'utilisateur au formulaire de calcul de subvention.
J'aimerais savoir si quelqu'un à une solution éventuel a savoir que j'ai une table Region une table Departement et une table Ville .
Je précise je n'est aucun probleme à récupérer mes données mais bien sur lorsque je fais un find de toutes les villes (42000 villes) j'ai une bonne grosse erreur concernant la limite de donéees.
je link l'erreur ci- dessous.
Cordialement à tous si besoin je peut link mon code sans souci .
Hello,
je vois plusieurs voies possibles :
1 - tu fais un premier SELECT avec les régions, une fois celle ci choisie un 2ème SELECT affiche les villes de cette région
2 - tu fais un INPUT dans lequel tu demandes le Code Postal, ce qui permet dans un SELECT d'afficher une petite liste de ville
3 - tu fais un INPUT avec le nom de la ville, qui rafraichie une liste de villes qui commencent par les caractères tappés dans le input
Evidemment il faut que chaque villes soient liées à une région et/ou code postal, je ne sais pas si tu disposes déja de ces liaisons ?
Oui les villes sont associer aux departements et j'ai bien les code postaux des villes
Oui mais le problemes reste que je dois faire un find all De mes villes et le chargement est treS tres tres long au demarrage de l appli
Justement non,
tu n'as besoin que d'un find('list') de tes régions.
Pour les villes tu peux n'en charger que certaines dans ton SELECT en ajax. (à la manière de remoteChained : http://www.appelsiini.net/projects/chained )
je te montre mes associations
app/model/Region
public $hasMany = array(
'Departement' => array(
'className' => 'Departement',
'foreignKey' => 'region_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
app/model/Departement
public $belongsTo = array(
'Region' => array(
'className' => 'Region',
'foreignKey' => 'region_id',
'conditions' => '',
'fields' => 'Region.name',
'order' => ''
)
);
public $hasMany = array(
'Ville' => array(
'className' => 'Ville',
'foreignKey' => 'departement_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
app/model/Ville
public $belongsTo = array(
'Departement' => array(
'className' => 'Departement',
'foreignKey' => 'departement_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
Pour faire quelque chose du même genre que la solution 1 que j'ai proposé j'ai utilisé "chosen" et "chained"
il faut la liste des régions ou département (on va dire que c'est la grosse échelle, avec un nombre limité d'entrées)
En plus de tes 3 models, il faut créer les models de liaison type : VilleDepartement avec des belongsTo Ville et Departement
Mais aussi un model Subvention et lien entre Ville et Subvention
Controller/Subvention->index
$departements = $this->Subvention->Ville->Departement->find('list');
$this->set(compact('departements'));
View/Subvention/index
echo $this->Form->input('Subvention.departement_id', array('multiple' => false));
echo $this->Form->input('Subvention.ville_id', array('multiple' => false));
$this->Html->css('chosen/chosen.min', null, array('inline' => false));
$this->Html->script('chosen/chosen.jquery.min', array('inline' => false));
$this->Html->script('chained/jquery.chained.remote.min', array('inline' => false));
$this->Html->scriptStart(array('inline' => false)); ?>
(function($){
$('#SubventionDepartementId').chosen({search_contains: true});
$("#SubventionVilleId").remoteChained({
parents : "#SubventionDepartementId",
url : "<?= $this->Html->url( array( 'controller' => 'Subvention', 'action' => 'ajaxSelect' ), true ); ?>",
})
.chosen({search_contains: true});
var selects = $('#SubventionDepartementId, #SubventionVilleId');
selects.on('change', function(){selects.trigger('chosen:updated');});
})(jQuery);
<?php $this->Html->scriptEnd(); ?>
Controller/Subvention->ajaxSelect
Il faut renvoyer la list en JSON du SELECT des villes (du département en question évidemment)
En me relisant je viens de me dire que tu ne voulais peut etre pas faire ca en ajax et que deux pages avec deux form ca serait bien plus simple (mais ca revient au même que le remoteChained qui se fait en 1 page)
1 - page 1 : select des départements
2 - tu soumets ton form, on récupère le departement_id
3 - on est redirigé vers la page 2 qui construit un select des villes qui ont un département_id = à celui qui vient d'être soumis.
4 - tu soumets ton form, on récupère ainsi le ville_id
En local c'est un WAMP? MAMP? un machine virtuelle avec LAMP? Tu as des timetout php parfois ? la requête mets combien de temps à s'éxécuter ?
Alor c est un wamp est oui effectivement j ai une erreur concernant la mémoire allouer , sa prend au moins 20 seconde a charger si je met une limit a 2000 Par exemple mais du coup je ne recupere que 2000 ville sur les 42000
Quand je me connecte à mon application en loadant toutes mes villes voila le joli message.
De le faire en ajax ne me derange pas car pour faire cours avant dans mon formulaire j'ai des traitements de valeur que je recupere de mon formulaire, mais le but est de faire tous mon formulaire sur la meme page.
En effet, il y a un soucis... Car sur mon MAMP pour faire une requete de 4000 entrées prend 20ms
Sur phpmyadmin -> ta table 'villes' -> Opérations -> Maintenance de la table
Dans ce menu il y a plusieurs outils que tu peux tester, surtout "Optimiser la table"
Ensuite en bas de ton layout tu peux ajouter ca :
<?php echo $this->element('sql_dump'); ?>
Regarde sur une requete avec une LIMIT de 1000, en bas de page tu auras des stats sur le nombre de ligne, le temps, etc.
Ca pourrait permettre de détecter ce qui prend du temps.