Deux modèles (Rails 2.3.8):rails named_scope ne tient pas compte de chargement désireux
- utilisateur; nom d'utilisateur & propriétés désactivées; Utilisateur has_one: profil
- Profil; full_name & propriétés cachées
J'essaie de créer un named_scope qui élimine les profils utilisateur disabled = 1 et hidden = 1. Le modèle User est généralement utilisé en conjonction avec le modèle Profile, donc j'essaye de charger rapidement le modèle Profile (: include =>: profile).
J'ai créé un named_scope sur le modèle de l'utilisateur appelé « visible »:
named_scope :visible, {
:joins => "INNER JOIN profiles ON users.id=profiles.user_id",
:conditions => ["users.disabled = ? AND profiles.hidden = ?", false, false]
}
J'ai remarqué que lorsque j'utilise la named_scope dans une requête, l'instruction de chargement avide est ignorée.
Variation 1 - modèle utilisateur uniquement:
# UserController
@users = User.find(:all)
# User's Index view
<% for user in @users %>
<p><%= user.username %></p>
<% end %>
# generates a single query:
SELECT * FROM `users`
Variation 2 - utiliser le modèle d'un profil en vue; charge paresseux modèle de profil
# UserController
@users = User.find(:all)
# User's Index view
<% for user in @users %>
<p><%= user.username %></p>
<p><%= user.profile.full_name %></p>
<% end %>
# generates multiple queries:
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 1) ORDER BY full_name ASC LIMIT 1
SHOW FIELDS FROM `profiles`
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 2) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 3) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 5) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 6) ORDER BY full_name ASC LIMIT 1
Variation 3 - charge désireux modèle de profil
# UserController
@users = User.find(:all, :include => :profile)
#view; no changes
# two queries
SELECT * FROM `users`
SELECT `profiles`.* FROM `profiles` WHERE (`profiles`.user_id IN (1,2,3,4,5,6))
Variation 4 - Utilisation name_scope, y compris l'instruction désireux de chargement
#UserConroller
@users = User.visible(:include => :profile)
#view; no changes
# generates multiple queries
SELECT `users`.* FROM `users` INNER JOIN profiles ON users.id=profiles.user_id WHERE (users.disabled = 0 AND profiles.hidden = 0)
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 1) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 2) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 3) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4) ORDER BY full_name ASC LIMIT 1
Variation 4 ne renvoie le nombre correct des enregistrements, mais semble également ignorer l'instruction de chargement enthousiaste.
Est-ce un problème avec les étendues nommées inter-modèles? Peut-être que je ne l'utilise pas correctement.
Est-ce que ce genre de situation est mieux géré par Rails 3?
OK. Je pourrais déplacer l'attribut caché vers le modèle User pour éviter complètement cette situation, mais il vaut probablement mieux que je trouve une autre approche pour ce type de situation. Pouvez-vous en penser un? – craig
Vous pouvez créer une autre association: 'User has_one: visible_profile'. Ensuite, vous appelez @ user.visible (: include =>: visible_profile), quand 'visible' est le named_scope avec seulement cette condition:' ["disabled =?", False] '. C'est comme l'exemple sur 'railsapi.com'. –
@j: J'ai ajouté une association au modèle User - has_one: visible_profile,: class_name => 'Profile',: conditions => ["profiles.hidden =?", False]. Changé le modèle d'utilisateur named_scope - named_scope: visible, { : conditions => ["disabled =?", False] } modifié l'action d'index UserController - @users = User.visible (: all,: include =>: visible_profile) . Serveur redémarré. Chargement paresseux qui se produit encore. Filtre de modèle de profil ignoré. Pensées? – craig