【问题标题】:Rails 3 Limiting Included ObjectsRails 3限制包含的对象
【发布时间】:2011-07-16 19:59:10
【问题描述】:

例如,我有一个博客对象,该博客有很多帖子。我想预先加载第一个博客对象,并包括它的前 10 篇文章。目前我会做@blogs = Blog.limit(4),然后在视图中使用@blogs.posts.limit(10)。我很确定有更好的方法可以通过 Blog.include(:posts).limit(:posts=>10) 之类的包含来做到这一点。是不能限制包含对象的数量,还是我在这里遗漏了一些基本的东西?

【问题讨论】:

  • 奇怪,我什至无法在 Rails(3.1) 控制台中使用这种方法。添加has_many :recent_posts, :class_name => 'Post', :limit => 3。但是当我Blog.includes(:posts).first 时,我仍然得到了所有的帖子,而不仅仅是前 3 个。
  • 试试 Blog.includes(:recent_posts).first.recent_posts
  • 你说得对,它也对我不起作用。该限制不适用于帖子查询。奇数。

标签: ruby-on-rails ruby-on-rails-3 activerecord eager-loading


【解决方案1】:

在急切加载多条记录的关联时,您似乎无法对 :has_many 应用限制。

例子:

class Blog < ActiveRecord::Base
  has_many :posts, :limit => 5
end

class Post < ActiveRecord::Base
  belongs_to :blog
end

这适用于限制单个博客的帖子数量:

ruby-1.9.2-p290 :010 > Blog.first.posts
  Blog Load (0.5ms)  SELECT `blogs`.* FROM `blogs` LIMIT 1
  Post Load (0.6ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`blog_id` = 1 LIMIT 5

但是,如果您尝试加载所有博客并急切地加载它们的帖子:

ruby-1.9.2-p290 :011 > Blog.includes(:posts)
  Blog Load (0.5ms)  SELECT `blogs`.* FROM `blogs` 
  Post Load (1.1ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`blog_id` IN (1, 2)

请注意,第二个查询没有限制,而且不可能 - 它会将所有博客中返回的帖子数量限制为 5,这根本不是您想要的。

编辑:

查看Rails docs 可以确认这一点。你总能在你弄明白这些东西的那一刻找到它们:)

如果您急切地加载具有指定 :limit 选项的关联,它 将被忽略,返回所有关联的对象

【讨论】:

  • 那么在这种情况下该怎么办呢?
【解决方案2】:

您需要像这样限制博客模型中的帖子数量:

class Blog < ActiveRecord::Base
    has_many :included_posts, :class_name => 'Post', :limit => 10
    has_many :posts
end

那么你可以这样做:

$ Blog.first.included_posts.count
=> 10
$ Blog.first.posts.count 
=> 999

【讨论】:

  • 但这不会限制每个博客的帖子总数吗?
  • 对,但是你可以创建多个有很多关联。见代码。
  • 我知道它是如何工作的,但是否也可以在查询中获取博客对象? @blogs = Blog.limit(3).recent_posts 实际上给了我一个帖子数组,但不是最初的父博客。如果有意义的话,我正在尝试优化我的数据库/查询使用。
  • blog = Blog.find(3).include(:included_posts)
猜你喜欢
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多