Mongoid:如何仅通过引用加载延迟加载的对象的某些字段?

时间:2012-05-07 08:29:26

标签: ruby-on-rails-3 mongoid lazy-loading model-associations

出于性能原因,我在编写mongoid查询时尽可能频繁地使用only()关键字来指定我要加载的字段。

通常的嫌疑人,例如,当我想要所有管理员的用户电子邮件仅用于显示目的时。

我会写:

User.where(:groups => :admins).only(:email).each do |u|
 puts u.email
end

我之所以这样做,是因为我的用户模型中充满了大量数据,在列出大量电子邮件时我很乐意忽略这些数据。

但是,现在让我们想象一下,我的用户是通过Project模型引用的,因此我可以为每个项目执行:project.user。感谢mongoid的延迟加载,我的对象用户只有在调用引用时才会被实例化(并从数据库中查询)。

但是如果我想列出所有管理项目所有者的所有电子邮件呢?

我会这样写:

Project.where(:admin_type => true).each do |p|
  puts p.user.email
end

这里的主要问题是,这样做,我为每个项目加载整个用户对象,如果有很多项目匹配查询可能会非常繁重。那么如何只加载电子邮件呢?

我可以这样做:

User.where(:_id => p.user_id).only(:email).first.email

但这显然违背了简单做法的好语法的目的:

p.user.email 

我希望我能写出像p.user.only(:email).email这样的东西,但我不能。有什么想法吗?

亚历

2 个答案:

答案 0 :(得分:6)

来自Mongoid的创建者的回答。这还不可能。它已被添加为功能请求。

答案 1 :(得分:2)

我认为你需要在这里进行非规范化。首先,阅读A Note on Denormalization

你可以使用mongoid事件自我实现非规范化或使用伟大的mongoid_denormalize gem。它很直接,在实现之后,您可以在查询中使用p.user_email或其他内容。