Ruby on Rails:一旦您急切地加载了具有条件的关联,如何在不再次接触数据库的情况下获取它?
想象一个像这样的简单情况:
class Book
has_many :chapters
end
假设在我的控制器中我做了这样的事情:
book = Book.find(:first,
:include => :chapters,
:conditions => ['chapters.title = ?', "In the beginning"]
现在假设我想显示该章节。如何在不再次访问数据库的情况下处理 Rails 中的章节?如果我这样做:
chapters = book.chapters.select{|chapter| chapter.title == "In the beginning"}
Rails 是否会重新访问所有章节的数据库,以便它可以扫描它们,然后更糟糕的是,必须在控制器代码中再次扫描它们?
看起来像这样使用 find 的东西:
chapters = Chapter.find_by_book_id_and_title(book.id, "In the beginning")
即使章节已经缓存,也会导致数据库再次被命中。
Imagine a simple case like this:
class Book
has_many :chapters
end
Let's say in my controller I do something like this:
book = Book.find(:first,
:include => :chapters,
:conditions => ['chapters.title = ?', "In the beginning"]
Now let's say I want to display the chapter. How can I address the chapters in Rails without hitting the database again? If I do something like this:
chapters = book.chapters.select{|chapter| chapter.title == "In the beginning"}
will Rails rehit the database for all of the chapters so that it can scan them, and then worse yet, have to scan them all again in the controller code?
And it seems like something that uses find like this:
chapters = Chapter.find_by_book_id_and_title(book.id, "In the beginning")
causes the database to be hit again even if it the chapter is already cached.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用 :include => :chapters 应该将其全部取回,根据 AR 总共会产生 2 个查询关联API。从那里您应该能够遍历数据而无需再次接触数据库。循环浏览 book.chapters 就很简单了,所有数据都应该在手边。
请注意,ActiveRecord 仅缓存最后一个查询,因此通过执行像 Chapter.find_by_book_id_and_title('title') 这样的不同查询,您之前的 Book.chapters 查询将不会被缓存(因为它完全不同)。
Using :include => :chapters should fetch it all back resulting in a total of 2 queries according to the AR Association API. From there you should be able to traverse the data without touching the database again. It's a simple matter of looping through book.chapters at that point, all the data should be on hand.
Note that ActiveRecord only caches the last query, so by doing a different query like Chapter.find_by_book_id_and_title('title') your prior Book.chapters query won't be cached (because it is entirely different).