PROBLÈMERails ActiveRecord Code amical d'un complexe Join, Somme et Regrouper
Bonjour,
J'ai pas de chance d'essayer de briser cette instruction SQL dans ActiveRecord/Rails de code amical et je J'aimerais apprendre comment je peux éviter une instruction find_by_sql dans cette situation.
Scénario J'ai des utilisateurs qui créent des audits lorsqu'ils effectuent une action. Chaque audit a une spécificité audit_activity. Chaque audit_activity vaut un certain nombre de points, basés sur score_weight. J'ai besoin de trouver les scores totaux de chaque utilisateur, en fonction de leur total cumulé audit_activity score_weights. Finalement, je vais devoir les classer, ce qui signifie ajouter une sorte à cela aussi bien.
Mon code Voici ma version sql et simplifiée des tableaux en question. Des pensées?
SQL avec les noms de colonnes complètes (pour plus de clarté)
SELECT users.id, u.email, SUM(audit_activity.score_weight)
FROM users
JOIN audits ON users.id = audits.user_id
JOIN audit_activities ON audit_activities.id = audits.audit_activity_id
GROUP BY users.id;
Modèles: utilisateur, vérification, AuditActivity
Les champs de l'utilisateur: id, email
class User < ActiveRecord::Base
include Clearance::User
has_many :audits
end
champs d'audit: id, user_id , audit_activity_id
class Audit < ActiveRecord::Base
belongs_to :user
belongs_to :audit_activity
end
champs AuditActivity: id, score_weight
class AuditActivity < ActiveRecord::Base
has_many :audits
end
Exemple de données
Voici un ensemble d'instructions SQL afin que vous puissiez jouer avec des données similaires, je travaille avec et voir ce qui arrive quand l'intéressé la requête est exécutée. Vous devriez juste pouvoir copier/coller le tout dans un navigateur de requête de base de données.
CREATE TABLE users(
id INTEGER NOT NULL,
email TEXT (25),
PRIMARY KEY (id)
);
CREATE TABLE audits(
id INTEGER NOT NULL,
user_id INTEGER,
audit_activity_id INTEGER,
PRIMARY KEY (id)
);
CREATE TABLE audit_activities(
id INTEGER NOT NULL,
score_weight INTEGER,
PRIMARY KEY (id)
);
INSERT INTO users(id, email)
VALUES(1, "[email protected]");
INSERT INTO users(id, email)
VALUES(2, "[email protected]");
INSERT INTO users(id, email)
VALUES(3, "[email protected]");
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(1, 1, 1);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(2, 1, 2);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(3, 1, 1);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(4, 1, 3);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(5, 1, 1);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(6, 1, 4);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(7, 2, 4);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(8, 2, 4);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(9, 2, 4);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(10, 3, 3);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(11, 3, 2);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(12, 3, 2);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(13, 3, 2);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(14, 3, 3);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(15, 3, 1);
INSERT INTO audits(id, user_id, audit_activity_id)
VALUES(16, 3, 1);
INSERT INTO audit_activities(id, score_weight)
VALUES(1, 1);
INSERT INTO audit_activities(id, score_weight)
VALUES(2, 2);
INSERT INTO audit_activities(id, score_weight)
VALUES(3, 7);
INSERT INTO audit_activities(id, score_weight)
VALUES(4, 11);
La requête Encore une fois, est la requête ici.
SELECT u.id, u.email, SUM(aa.score_weight)
FROM users u
JOIN audits a ON u.id = a.user_id
JOIN audit_activities aa ON aa.id = a.audit_activity_id
GROUP BY u.id;
Ceci est très proche à ce que j'ai jusqu'ici. Voyant que vous êtes arrivé avec quelque chose de très similaire, je commence à pencher plus vers cela. La vôtre, cependant, est beaucoup plus propre. Ce que j'avais: User.calculate (: sum, 'audit_activities.score_weight',: jointures => ['Audits INNER JOIN ON audits.user_id = utilisateurs.id', 'INNER JOIN audit_activities ON audit_activities.id = audits. audit_activity_id '],: order =>: sum_id,: group =>' users.id ') –