JeuWeb - Crée ton jeu par navigateur
[Résolu][Rails] Une incrémentation de sequence SQL dans une boucle for .. in - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Résolu][Rails] Une incrémentation de sequence SQL dans une boucle for .. in (/showthread.php?tid=5708)



[Résolu][Rails] Une incrémentation de sequence SQL dans une boucle for .. in - Maz - 25-09-2011

Salut! Non pas que je veuilles flooder, mais je suis actuellement en "plein boom". Et qui dis plein boom dis plein de bug XD.

Mon soucis actuel est le suivant:
à la création de chaque compte joueur, une sequence est créé. Ceci dans le but que les fourmis de chaques joueurs soient uniques:
Joueur1:
fourmis 1
fourmis 2
fourmis 3

Joueur2:
fourmis 1
fourmis 2
fourmis 3

La création de la sequence marche impecablement via cette instruction:
ActiveRecord::Base.connection.execute("CREATE SEQUENCE fourmis_" + current_user.username + "_id_seq MINVALUE 0")

Mais à la création de chaque fourmis, j'ai un léger problème. Le joueur peut choisir autant de fourmis qu'il veut créé, je dois donc à chaque fois:
créé l'objet fourmis, lui assigné pour nom la prochaine valeur de la sequence donc en même temps incrémenté la sequence.

Mon soucis est que cette instruction est dans une boucle que voici:
for i in 0 .. @quantity
current_user.city.ants.build(Confusedort => "bip",
:born => Time.now + i*6 + @decalage,
:name => ActiveRecord::Base.connection.select_value("SELECT nextval('fourmis_" + current_user.username + "_id_seq')"))
end
Chaque fourmis est créé impecablement, je parles notament du champs "born", qui est très bien incrémenter de 6secondes à chaque passage de boucle.
Mais mon instruction nextval(sequence), est incrémenté une seule fois puis assigné à toute les fourmis. Ainsi le joueur qui cré ses fourmis deux par deux se retrouves avec:
fourmis 1
fourmis 1
fourmis 2
fourmis 2
fourmis 3
fourmis 3
...

Quelqu'un as-t'il déjà était confronté à ce problème? Je peut très bien stocké la valeur du nextval avant de boucler, lui ajouter i à chaque passage de boucle et en fin de boucle stocké le nom de la dernière fourmis dans la sequence, mais c'est un peu primitif je trouves ,)

EDIT: Ok, j'ai trouvé le problème:
Citation : (8.6ms) SELECT nextval('fourmis_Maz_id_seq')
CACHE (0.0ms) SELECT nextval('fourmis_Maz_id_seq')
CACHE (0.0ms) SELECT nextval('fourmis_Maz_id_seq')
CACHE (0.0ms) SELECT nextval('fourmis_Maz_id_seq')
CACHE (0.0ms) SELECT nextval('fourmis_Maz_id_seq')

Les requêtes sont mises en cache! Maintenant il n'y a plus qu'à résoudre =)

EDIT²: Ok, résolu grâce à la fonction ActiveRecord::Base.connection.disable_query_cache!


RE: [Rails] Une incrémentation de sequence SQL dans une boucle for in > Soucis. - Sephi-Chan - 25-09-2011

Simple, la méthode uncached permet de désactiver le query cache à la demande :


uncached do
# Ton code...
end


Au passage, je te déconseille d'utiliser la notation for .. in en Ruby : ce n'est pas dans l'esprit du langage.
Et dans ton cas précis, tu devrais utiliser la méthode upto.


0.upto(@quantity) do |i|
# ...
end



RE: [Rails] Une incrémentation de sequence SQL dans une boucle for in > Soucis. - Maz - 25-09-2011

(25-09-2011, 01:24 PM)Sephi-Chan a écrit : Simple, la méthode uncached permet de désactiver le query cache à la demande :


uncached do
# Ton code...
end


Au passage, je te déconseille d'utiliser la notation for .. in en Ruby. Ce n'est pas dans l'esprit du langage.
Dans ton cas précis, tu devrais utiliser la méthode upto.


0.upto(@quantity) do |i|
# ...
end

Je suis tombé sur la solution du uncached (je vous assures que je cherches avant de poster!), mais résultat:
Citation :undefined method `uncached' for #<Panel::AntsController:0xaac02b0>

Merci pour le upto, je ne connaissais pas.


RE: [Rails] Une incrémentation de sequence SQL dans une boucle for in - Sephi-Chan - 25-09-2011

C'est parce que tu fais ça dans le contrôleur et que c'est une méthode exposée dans le modèle.
Regarde ma réponse dans l'autre topic, tu verras que j'y propose une solution qui délègue plus de choses au modèle pour un code plus lisible et testable. Smile