JeuWeb - Crée ton jeu par navigateur
[Résolu][Rails] Récupération de données composites de PostgreSQL avec MonModel.select - 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] Récupération de données composites de PostgreSQL avec MonModel.select (/showthread.php?tid=5711)

Pages : 1 2 3 4


[Résolu][Rails] Récupération de données composites de PostgreSQL avec MonModel.select - Maz - 27-09-2011

Salut! C'est encore bibi, je suis en train de m'arracher le peu de cheveux qui me restes (je les ai joué à pile ou face il y a de ça 15jours...), sur ce tout petit bout de code:
last_created_city = City.select("position[0] as x, position[1] as y").last
unless last_created_city.nil?

x = last_created_city.x.to_f
y = last_created_city.y.to_f
logger.debug "--------------------------DEBUG----------------------"
logger.debug "x = #{x} y = #{y}"
end

Le SQL généré est parfait comme je le veut:
SELECT position[0] as x, position[1] as y FROM "cities" ORDER BY "cities"."id" DESC LIMIT 1

Lorsque j'exécutes ce bout de SQL directement dans ma BDD j'obtiens les valeurs: x = -12 y = -18
Lorsque j'exécute le code ruby j'obtiens dans la console grâce au debug les valeurs: x = -12 y = 0

Est-ce que vous voyez quelque chose de louche?

Le code entier de la fonction est le suivant:
def self.where_to_live!
x = 0
y = 0
last_created_city = City.select("position[0] as x, position[1] as y").last
unless last_created_city.nil?

x = last_created_city.x.to_f
y = last_created_city.y.to_f
logger.debug "--------------------------DEBUG----------------------"
logger.debug "x = #{x} y = #{y}"
x /= SPACE_BETWEEN_CITIES
y /= SPACE_BETWEEN_CITIES

x = x.floor
y = y.floor
logger.debug "Floor:"
logger.debug "x = #{x} y = #{y}"

if x == y
logger.debug "x = y"
axis = "x"
direction = x < 0 ? "+" : "-"
elsif x.abs == y.abs
logger.debug "x.abs == y.abs"
axis = y > 0 ? "x" : "y"
direction = y > 0 ? "-" : "+"
elsif x.abs > y.abs
logger.debug "x.abs > y.abs"
axis = "y"
direction = x > 0 ? "+" : "-"
elsif y.abs > x.abs
logger.debug "y.abs > x.abs"
axis = "x"
direction = y > 0 ? "-" : "+"
else
raise ArgumentError, "Error occured"
end
logger.debug "Direction: #{direction}"

if axis == "x"
x = direction == "+" ? x+1 : x-1
elsif axis == "y"
y = direction == "+" ? y+1 : y-1
else
raise ArgumentError, "Error occured"
end
end

x = x*SPACE_BETWEEN_CITIES + rand(CITIES_RANDOM_AREA)
y = y*SPACE_BETWEEN_CITIES + rand(CITIES_RANDOM_AREA)
"(#{x},#{y})"
end

Merci beaucoup pour toutes pistes, ça va faire 24h que je suis dessus, ça commences à me trotter même au boulot ^^.


RE: [Rails] Récupération de donnée via Class.select("SQL").last - Sephi-Chan - 27-09-2011

Dur, dur. D'après ce que tu disais, ces types sont propres à Postgres, non ? Il faudrait que tu détailles ça pour qu'on puisse recréer l'environnement en local.
Je doute que ActiveRecord supporte ça puisque ce type de données composite est propre à un système.

As-tu regardé du côté de la gem Spatial Adapter ?


Et j'en profite pour proposer un petit changement :


unless last_created_city.nil?
if last_created_city

Et le nom me semble inadapté puisque la convention veut que les méthodes d'un modèle qui s'achève par un ! indique qu'une sauvegarde sera effectuée, avec une exception en cas d'échec.


RE: [Rails] Récupération de donnée via Class.select("SQL").last - Maz - 27-09-2011

(27-09-2011, 12:35 AM)Sephi-Chan a écrit : Dur, dur. D'après ce que tu disais, ces types sont propres à Postgres, non ? Il faudrait que tu détailles ça pour qu'on puisse recréer l'environnement en local.
Je doute que ActiveRecord supporte ça puisque ce type de données composite est propre à un système.

As-tu regardé du côté de la gem Spatial Adapter ?


Et j'en profite pour proposer un petit changement :


unless last_created_city.nil?
if last_created_city

Et le nom me semble inadapté puisque la convention veut que les méthodes d'un modèle qui s'achève par un ! indique qu'une sauvegarde sera effectuée, avec une exception en cas d'échec.

Et bien oui, le champs position est de type point, spécial à PostgreSQL. Mais je récupères position[0] as x et position[1] as y (merci PostgreSQL ,P) qui renvois deux int x et y donc je ne vois pas de soucis de compatibilité possible, ça marches très bien pour x, pourquoi pas y...


RE: [Rails] Récupération de donnée via Class.select("SQL").last - niahoo - 27-09-2011

peut-être justement parce que rails ne lit qu'une seule donnée de la base, il ne sait pas que le type point renvoie deux valeurs distinctes


RE: [Rails] Récupération de donnée via Class.select("SQL").last - Sephi-Chan - 27-09-2011

Exactement. Cette façon de faire étant propre à PostgreSQL, l'adapter généraliste de ActiveRecord ne sait probablement pas la traiter.
Le plus raisonnable et facile d'utilisation me semble être un adapteur spécifique : ça permettra de garder un code bien objet sans te soucier de la partie sélection.



RE: [Rails] Récupération de donnée via Class.select("SQL").last - Maz - 27-09-2011

Si c'est le cas c'est "bouuuh ActiveRecord" ,P

je test dans 30min quand je serais come back home =)


RE: [Rails] Récupération de donnée via Class.select("SQL").last - Sephi-Chan - 27-09-2011

Tu peux critique ActiveRecord, mais ça ne servira à rien. Ce n'est pas dans sa vocation de gérer les fonctionnalités spécifiques à chaque SGBDR.
D'où l'invention d'adapter spécialisés.



RE: [Rails] Récupération de donnée via Class.select("SQL").last - Maz - 27-09-2011

Oui mais dans ce cas là le SGBDR fait tout le boulot et renvoi simplement 2int! C'est comme si je faisait "select x, y from matable", x y étant 2champs bien distinct de type int.


RE: [Rails] Récupération de donnée via Class.select("SQL").last - Sephi-Chan - 27-09-2011

Et tu comptes te taper le dispatch de ces attributs composites à chaque fois que tu fais une requête ? Confusediffle:
Essaye l'adapter et tiens-nous au courant. :p


RE: [Rails] Récupération de donnée via Class.select("SQL").last - Maz - 27-09-2011

Oui oui, j'essaie, mais à peine installer que ça fait planter toute mon app... j'ai essayer hier un autre adapter: GeoRuby, j'ai jamais réussis a récupéré un point lol.