Bonjour,
J'ai un modèle Rails dans lequel je suis en train de sérialiser un tableau d'informations. Deux choses sont importantes pour moi :
- Je veux pouvoir m'assurer qu'il est unique (c'est-à-dire qu'il ne peut y avoir deux modèles avec le même tableau).
- Je veux pouvoir rechercher des modèles existants pour ce hachage (dans une sorte de méthode find_or_create_by).
Ce modèle décrit un "portefeuille", c'est-à-dire un groupe d'actions ou d'obligations. Le tableau est la description des titres qui se trouvent dans le portefeuille, et dans quelles pondérations. J'ai également un deuxième modèle, qui est un groupe de portefeuilles (appelons-le "collection de portefeuilles" pour garder les choses simples). Une collection a plusieurs portefeuilles, et un portefeuille peut être dans plusieurs collections. En d'autres termes :
class Portfolio
serialize :weights
has_and_belongs_to_many :portcollections
class Portcollection
has_and_belongs_to_many :portfolios
Lorsque je génère une "collection de portefeuilles", je dois construire un certain nombre de portefeuilles, ce que je fais de manière programmatique (l'implémentation n'est pas importante). Construire un portefeuille est une opération coûteuse, donc j'essaie de vérifier l'existence d'un portefeuille en premier lieu. Je pensais pouvoir le faire via find_or_create_by, mais je n'ai pas eu beaucoup de chance. Voici ma solution actuelle :
Class Portcollection
before_save :build_portfolios
def build_portfolios
……
proposed_weights = ……
yml =proposed_weights.to_yaml
if port = Portfolio.find_by_weights(yml)
self.portfolios << port
else
self.portfolios << Portfolio.create!(:weights => proposed_weights)
end
……..
end
Cela fonctionne, mais c'est assez lent. J'ai l'impression que c'est parce que je convertis mes données en YAML à chaque fois que j'essaie de vérifier si un portefeuille existe (cela s'exécute probablement des millions de fois), et que je recherche une chaîne de caractères plutôt qu'un nombre entier. J'ai cependant un index sur cette colonne.
Existe-t-il une meilleure façon de procéder ? Quelques pensées m'ont traversé l'esprit :
- Calculer un hash MD5 du tableau "weights", et le sauvegarder dans une colonne de la base de données. Je devrai toujours calculer ce hachage chaque fois que je veux rechercher un tableau, mais j'ai l'impression que ce serait plus facile pour la base de données d'indexer et de rechercher ?
- Travailler sur le passage de has_and_belongs_to_many à has_many => through, et stocker les informations du tableau comme des colonnes de la base de données. De cette façon, je pourrais essayer d'élaborer une requête de base de données qui pourrait vérifier l'unicité, sans YAML ou sérialisation
c'est-à-dire quelque chose comme :
class Portfolio
has_many :portcollections, :through => security_weights
class Portcollections
has_many :portfolios, :through => security_weights
SECURITY_WEIGHTS
id portfolio_id portcollection_id weight_of_GOOG weight_of_APPLE ……
1 14 15 0.4 0.3
Au cas où cela serait important, le tableau des "poids" ressemblerait à ceci :
[ [‘GOOG’, 0.4] , [‘AAPL’, 0.3] , [‘GE’, 0.3] ]
Toute aide serait appréciée. N'oubliez pas que je suis un amateur - la programmation n'est qu'un passe-temps pour moi ! Veuillez m'excuser si je fais quelque chose de très compliqué ou si je manque quelque chose d'évident.....
Merci !
MISE À JOUR 1
J'ai fait quelques recherches sur la méthode "store" de Rails 3.2, mais cela ne semble pas être la solution non plus... Elle stocke simplement les objets en JSON, ce qui me donne le même manque de possibilité de recherche que maintenant.