Voici une sélection imbriquée avec include:
@items = Item.where("complete = ?", true).includes( :manufacturer, {:order=>[:supplier, :agent] })
Il s'agit d'une requête astreignante, car elle extrait des milliers de lignes de données de toutes les tables incluses ci-dessus.
Comment puis-je obtenir la requête pour ne sélectionner que des champs spécifiques?
Il existe une méthode de sélection dans ARel, mais vous devez utiliser les noms de table corrects (au pluriel et méfiez-vous si vous avez des modèles polymorphes ou si vous utilisez set_table_name ou une autre pratique non standard similaire).
@items = Item.
select('users.name', 'users.created_at', 'orders.created_at', 'suppliers.name', 'agents.name', 'manufacturers.name').
where(:users => { :fulfilled => true }).
includes(:orders => [:supplier, :agent], :manufacturer)
"Nous pouvons utiliser select avec les jointures non incluses" - @Bhavesh_A_P
Comme @Bhavesh_A_P l'a souligné ci-dessus, select
avec includes
ne produit pas un comportement cohérent. Il semble que si l'association incluse ne renvoie aucun résultat, select
fonctionnera correctement. Si elle renvoie des résultats, l'instruction select n'aura aucun effet. En fait, il sera complètement ignoré, de sorte que votre instruction select pourrait faire référence à des noms de table non valides et qu'aucune erreur ne serait générée. select
avec joins
produira un comportement cohérent.
En fait, nous ne pouvons pas utiliser select with includes. Il ne peut être utilisé qu'avec des jointures.
Le problème n'est pas résolu en incluant un appel à la méthode 'select' dans la chaîne. Dans une ActiveRecord :: Relation similaire que nous avons construite, l'appel de "includes" semble remplacer tout appel à "select".
scope :active, where("hired_on < ? AND (separated_on > ? OR separated_on IS NULL)", Time.now, Time.now )
scope :with_role, lambda {|roles| includes(:team_member_roles).where(:team_member_roles => {:role => roles } ) }
scope :with_site_code, lambda {|site_codes| includes(:team_member_sites).where(:team_member_sites => {:site_code => site_codes } ) }
TeamMember.select("team_members.email, team_members.first_name, team_members.last_name").active.with_site_code(params[:site_code]).with_role(["senior_editing", "senior_and_reg_editing"])
Comme indiqué, la requête sélectionne toutes les colonnes.
Lorsque les 2 portées utilisent 'jointes' au lieu de 'inclut', la requête fonctionne: seules les 3 colonnes spécifiées sont sélectionnées.
Item.where("fulfilled = ?", true)
.includes({:orders =>[:suppliers, :agents]}, :manufacturers)
.select("users.name, users.created_at, orders.created_at, suppliers.name, agents.name").
.order('orders.created_at DESC')