Rails 3, custom raw instruction SQL insert
J'ai un modèle d'Évaluation. L'évaluation a plusieurs partitions. Chaque fois qu'une nouvelle évaluation est créé, un score record est créé pour chaque utilisateur qui a besoin d'une évaluation (voir ci-dessous pour la méthode actuelle, je suis en utilisant pour ce faire.) Ainsi, par exemple, 40 score enregistrements peuvent être créés à la fois. L'Évaluation propriétaire, alors les mises à jour de chaque score record avec le score de l'Utilisateur.
Je suis à la recherche d'utiliser SQL brut parce que chaque insert est sa propre transaction et il est lent.
Je voudrais le convertir en une masse instruction insert à l'aide de matières SQL:
def build_evaluation_score_items
self.job.active_employees.each do |employee|
employee_score = self.scores.build
employee_score.user_id = employee.id
employee_score.save
end
end
Des idées sur la façon dont cela peut être fait? J'ai essayé de l'adapter un exemple de code à partir de Chris Heald Café du site Propulsé mais, pas de dés.
Merci à tous ceux qui sont prêts à vous aider!
EDIT 1
J'ai négligé de mentionner la méthode actuelle est enveloppé dans une transaction.
Donc, essentiellement, je suis en train d'ajouter à cela le bloc de code, donc tout est inséré dans un énoncé (** Ce code snippit est de Chris Heald Café du site Propulsé qui a abordé le sujet. Je voudrais poser la question, mais le poste est > 3 ans.):
inserts = []
TIMES.times do
inserts.push "(3.0, '2009-01-23 20:21:13', 2, 1)"
end
sql = "INSERT INTO user_node_scores (`score`, `updated_at`, `node_id`, `user_id`)VALUES #{inserts.join(", ")}"
Je serais heureux de montrer le code de certains de mes tentatives qui ne fonctionnent pas...
Merci encore!
Bien, j'ai bricolé quelque chose qui ressemble au code ci-dessus, mais je reçois une instruction SQL invalide erreur autour de la ('evaluation_id' partie. Toutes les pensées?
def build_evaluation_score_items
inserts = []
self.job.active_employees.each do |employee|
inserts.push "(#{self.id}, #{employee.id}, #{Time.now}, #{Time.now})"
end
sql = "INSERT INTO scores ('evaluation_id', `user_id`, 'created_at', `updated_at`)VALUES #{inserts.join(", ")}"
ActiveRecord::Base.connection.execute(sql)
end
Aucune idée de ce dans les au-dessus de code SQL est à l'origine de l'erreur?
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error at or near "07" LINE 4: (1, 1, 100, 2017-02-20 07:00:56 +0000, 2017-02-20 07...
OriginalL'auteur Angelo Chrysoulakis | 2012-10-03
Vous devez vous connecter pour publier un commentaire.
Bien, après beaucoup d'essais et d'erreurs, voici la réponse finale. Le truc cool, c'est que tous les enregistrements sont insérés via une déclaration. Bien sûr, les validations sont ignorés (donc ce ne sera pas approprié, si vous avez besoin de modèle de validations sur créer), mais dans mon cas, ce n'est pas nécessaire, parce que je suis en train de faire est de configurer le score record pour chaque employé de l'évaluation. Bien sûr, les validations de travail comme prévu lors de l'emploi de chef de file des mises à jour de l'employé de l'évaluation du score.
Cela ne fonctionne pas pour moi parce que
time
a une mauvaise sortie. Postgres est de lancer ceci:ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error at or near "07" LINE 4: (1, 1, 100, 2017-02-20 07:04:11, 2017-02-20 07:04:11...
L'utilisation de insert pour vider le cache.
OriginalL'auteur Angelo Chrysoulakis
Plutôt que de construire de SQL directement à (et de vous ouvrir à l'injection SQL et d'autres questions), je vous recommande le activerecord-importation gem. Il peut émettre des multi-ligne
INSERT
commandes, entre autres stratégies.Vous pouvez écrire quelque chose comme:
OriginalL'auteur willglynn
Je pense que ce que vous cherchez est:
Tous les enfants les transactions sont automatiquement "poussé" à la mère de la transaction. Cela permettra d'éviter la surcharge de tant de transactions et devrait augmenter les performances.
Vous pouvez en lire plus à propos de ActiveRecord transactions ici.
Mise à JOUR
Désolé, j'ai mal compris. En gardant la réponse ci-dessus pour la postérité. Essayez ceci:
J'ai mis à jour ma réponse avec une solution potentielle. S'il vous plaît laissez-moi savoir si cela vous aide.
Salut Chuck - je suis d'accord avec le maintien de la premier élément, c'est pourquoi je upvoted. La méthode d'opération est de bon sens. Cela dit, malheureusement, j'obtiens l'erreur suivante: undefined method `exécuter' pour ActiveRecord::Base:la Classe. Je vais creuser autour appropriée pour l'exécution de la commande et en fera rapport.
OriginalL'auteur Chuck Callebs