2017-09-16 1 views
0

Donc dans mon application j'ai les modèles People et Outfits. Dans mon contrôleur de spectacle pour les gens, je reçois la liste comme ceci:Rails activerecord - comment hériter de toutes les associations enfants?

@people = Person.where("description LIKE ?", "%#{params[:description]}%") 

Et à mon avis, je montre les tenues de chaque personne comme ceci:

<% @people.each do |person| %> 
    <p> Name: <%= person.name %> </p> 
    <% @outfits = person.outfits %> 
    <% @outfits.each do |outfit| 
    <p> Name: <%= outfit.name %> </p> 
    <p> Description: <%= outfit.description %> </p> 
    <% end %> 
<% end %> 

mais en chargeant les tenues pour chaque personne, comme je charge beaucoup de gens sur la page, prend trop de temps. Y a-t-il un moyen pour que je puisse hériter des tenues de chaque personne afin de ne pas avoir à attendre le chargement de la page? Ou est le seul moyen d'accélérer cela pour faire un index entre les tenues et les gens? Merci pour toute aide

+0

Les réponses ci-dessous vous aidera à optimiser les performances des appels, mais vous devez également limiter ce que vous affichez en ajoutant une sorte de ou ayant la pagination capacité à montrer de plus en plus. – s1mpl3

Répondre

0

vous devez définir une limite comme ceci:

@people = Person.where("description LIKE ?", "%#{params[:description]}%").limit(20) 

changer le nombre en fonction de votre préférence.

2

Utilisez un membre pour charger les enregistrements associés:

@people = Person.eager_load(:outfits) 
       .where("description LIKE ?", "%#{params[:description]}%") 
       .limit(20) # optional 

Sinon, vous avez ce qu'on appelle un N + 1 numéro de requête où chaque itération par @people provoquera une requête de base de données séparée pour aller chercher des tenues.

Et oui le outfits.person_id ou n'importe quelle colonne qui crée l'association devrait avoir un index de clé étrangère. Utilisation de la belongs_to ou references macro dans la migration le fera par défaut:

create_table :outfits do |t| 
    t.belongs_to :person, foreign_key: true 
end 
+0

plus un décalage pour aider à la pagination. – s1mpl3

0

Vous pouvez utiliser .joins ou .includes

Si vous avez une table plein de Personne et vous utilisez un: join => outfits pour tirer tout Les informations de tenue à des fins de tri, etc, il fonctionnera bien et prend moins de temps que: inclure, mais dites que vous voulez afficher la personne avec le nom de la tenue, la description, etc. Pour obtenir l'information en utilisant: jointures, il devra faire des requêtes SQL séparées pour chaque utilisateur qu'il récupère, alors que si vous avez utilisé: include cette information est prête à l'emploi.

Solution

Person.includes(:outfits).where("description LIKE ?", "%#{params[:description]}%") 
+0

Si vous savez que vous utilisez les données dans la table jointe, il est préférable d'utiliser '.eager_load' car includes utilisera deux requêtes distinctes. – max