1
votes

Ruby on Rails - Comment faire une requête personnalisée?

J'ai 2 tables avec des millions d'enregistrements:

Le premier tableau est Abonnement et le deuxième tableau est Message .

Dans le tableau Subscription , j'ai 3 index:

  • subscription_id

  • msisdn

  • reporting_id

Cependant, dans la table Message , je n'ai que 2 index:

  • id_message

  • reporting_id

J'ai msisdn dans le tableau Message mais il n'est pas indexé.

J'ai donc une interface utilisateur de tableau de bord qui me permet de rechercher Message .

Je souhaite rechercher Message en utilisant msisdn mais comme msisdn n'est pas indexé, la requête prend une éternité!

mais je veux mettre l'idée de "Indexer msisdn dans la table Message " comme plan B.

Mon plan A est donc (pour lequel j'ai besoin d'aide):

Étant donné que les deux tables ont indexé reporting_id , je souhaite rechercher Message en utilisant subscription.msisdn dans le tableau de bord, puis à partir de là, Je souhaite utiliser le subscription.reporting_id et lister tous les Message avec cet subscription.reporting_id .

Quelque chose comme subscription.reporting_id = message.reporting_id .

J'ai la vue , le contrôleur et le modèle pour ces 2 tables,

J'ai essayé de faire cela dans les deux modèles

has_many: message, Foreign_key:: reporting_id dans Subscription.rb

et

appartient_à: abonnement dans Message.rb

mais cela n'a pas fonctionné.

Dans ma vue , le champ de recherche pour MSISDN recherche actuellement l'enregistrement à partir de subscription.msisdn

Quelqu'un sait-il comment puis-je y parvenir?

PS: je souhaite empêcher de modifier la structure du tableau.


2 commentaires

Les relations has_many doivent être plurielles, c'est-à-dire has_many: messages .


@MikeHeft, merci pour votre réponse, mais cela ne résout pas mon problème :(


3 Réponses :


2
votes

Si vous souhaitez établir une association has_many: messages dans la classe Subscription, vous devrez spécifier la primary_key.

Message.
 joins("INNER JOIN subscriptions ON subscriptions.reporting_id = messages.reporting_id").
 merge(Subscription.where(msisdn: "#{value}"))

Avec ceci, le SQL généré ressemblera à ceci:

SELECT "messages".* FROM "messages" WHERE "messages"."reporting_id" = $1  [["reporting_id", "#{reporting_id}"]]

La primary_key garantit la valeur de reporting_id du modèle Subscription est utilisé, sinon il sera par défaut dans la colonne id.

Cependant, plutôt que d'établir cette association qui ne semble pas exactement normalisée (au moins 3NF ), vous pouvez simplement avoir une requête pour trouver tous les messages en utilisant msisdn et reporting_id. Quelque chose comme celui-ci devrait toujours être efficace:

class Subscription < ApplicationRecord
  has_many :messages, foreign_key: "reporting_id", primary_key: "reporting_id"
end


1 commentaires

Merci pour votre réponse: D, j'ai essayé à la fois Kvr Ramya et votre suggestion, mais cela n'a pas fonctionné pour moi. Mais j'ai trouvé la solution basée sur le code de votre gars. J'ai écrit appartient_to: abonnement, clé étrangère: "reporting_id", primary_key: "reporting_id" dans Message.rb à la place.



1
votes

doit également ajouter une clé primaire has_many: message, Foreign_key:: reporting_id, primary_key:: reporting_id dans Subscription.rb


1 commentaires

Merci pour votre réponse: D, j'ai trouvé le correctif!



0
votes

J'ai trouvé la solution!

Dans mon Message.rb , j'ai fait:

SELECT  `subscription`.* FROM `subscription` WHERE `subscription`.`reporting_id` = '1eaa7a61fe635005c81df347b1a7c401' LIMIT 1

et il a généré cette requête

belongs_to :subscription, foreign_key: :reporting_id, primary_key: :reporting_id


0 commentaires