J'ai un modèle User
, que has_one :child
et le Child
modèle has_one :toy
.
Si j'ai une seule instance de la classe User user
Comment puis-je charger à la fois l'enfant et le jouet dans une seule requête ?
Voici ce qui ne fonctionne pas :
user.child.toy # 2 queries
user.includes(child: :toy) # can't call includes on a single record
user.child.includes(:toy) # same as above
user.association(:child).scope.eager_load(:toy).first # makes the appropriate query with both child and toy... but doesn't set the object on the user model.
user.child = user.association(:child).scope.eager_load(:toy).first # makes the appropriate query, but also calls another query before setting the child :(
Existe-t-il un moyen de faire cela sans avoir à réinterroger le modèle d'utilisateur, c'est-à-dire que je veux éviter cela ?
User.where(id: user.id).eager_load(child: :toy).first
Déclarations de modèle relatives :
class User < ActiveRecord::Base
has_one :child
has_one :toy, through: :child
end
class Child < ActiveRecord::Base
has_one :toy
belongs_to :user
end
class Toy < ActiveRecord::Base
belongs_to :child
end
Mise à jour
Cela fonctionne, mais n'est pas idéal. Je ne pense pas qu'il faille déclarer une autre relation uniquement pour cette raison.
class User < ActiveRecord::Base
has_one :child
has_one :toy, through: :child
has_one :child_with_toy, ->{ eager_loads(:toy) }, class_name: "Child", foreign_key: :parent_id
end
ce qui me permet d'appeler user.child_with_toy
pour obtenir le Child
et l'objet user.child_with_toy.toy
pour obtenir le Toy
tout en ne déclenchant qu'une seule requête SQL.