0

J'ai un modèle d'utilisateur. Tous les utilisateurs appartient à une entreprise, et les entreprises ont beaucoup de dossiers:Quelle est la meilleure façon d'écrire un "has_many: through" pour qu'il utilise une simple requête WHERE, au lieu d'une INNER JOIN?

class User < ApplicationRecord 
    belongs_to :company 
end 

class Company < ApplicationRecord 
    has_many :records 
end 

class Record < ApplicationRecord 
    belongs_to :company 
end 

J'utilise pour authentifier les utilisateurs Devise, alors je veux commencer toutes mes questions avec current_user, pour vous assurer que je ne les enregistrements de retour l'utilisateur est autorisé à voir. Je veux juste appeler quelque chose comme:

current_user.company_records 

(Je ne veux pas appeler current_user.company.records, parce que je ne ai pas besoin de charger la société que je dois juste les dossiers..)

Si je fais :

has_many :company_records, source: :records, through: :company 

Ensuite Rails ne une jointure interne, ce qui est brut:

2.3.3 :030 > user.company_records 
    Record Load (0.5ms) SELECT "records".* FROM "records" INNER JOIN "companies" ON 
    "records"."company_id" = "companies"."id" WHERE "companies"."id" = $1 [["id", 1]] 

Je dois faire t son:

has_many :company_records, 
      class_name: 'Record', 
      primary_key: :company_id, 
      foreign_key: :company_id 

Ensuite Rails il suffit d'exécuter un simple "où" la requête (qui a les index appropriés):

2.3.3 :039 > user.company_records 
    Record Load (0.4ms) SELECT "records".* FROM "records" WHERE "records"."company_id" = $1 [["company_id", 1]] 

est-il un moyen plus agréable d'écrire cela? Je pouvais faire:

def company_records 
    Record.where(company_id: company_id) 
end 

... mais je veux savoir s'il y a un moyen plus idiomatiques de le faire avec les associations ActiveRecord.

Répondre

0

Utilisez de préférence un délégué?

delegate :records, to: :company, prefix: true 

Ensuite, vous pouvez utiliser directement

current_user.company_records 
+0

Merci pour votre réponse, mais 'delegate' va également charger la compagnie avant de charger tous les enregistrements. C'est la requête inutile que j'essaie d'éviter. – ndbroadbent