我一直在阅读Rails 3 Way并正在检查CollectionAssociation.include?
根据书中的描述:
检查关联中是否存在提供的记录 集合,它仍然存在于底层数据库中 表
我做了几个测试来检查DB是否已经过检查,但看起来它没有检查。
> book = Book.first
=> #<Book id: 1, title: "Programming Ruby"...
> last_chapter = book.chapters.last
=> #<Chapter id: 2, title: "Chapter 2", book_id: 1,
> b.chapters.include?(last_chapter)
=> true
> last_chapter.destroy
DELETE FROM "chapters" WHERE "chapters"."id" = ? [["id", 2]]
=> #<Chapter id: 2, title: "Chapter 2", book_id: 1,
> b.chapters.include?(last_chapter)
=> true
> book.chapters.reload
=> [#<Chapter id: 1, title: "Chapter 1", book_id: 1,...]
> b.chapters.include?(last_chapter)
=> false
我检查了源代码并找到了一行load_target if options[:finder_sql]
,它似乎有条件地加载了记录。
您是否知道何时访问DB以检查DB中是否存在记录?
答案 0 :(得分:1)
Rails使用延迟加载和memoization。
这意味着b.chapters
在您第一次调用getter之前不会加载任何章节。
之后,由于记忆,销毁章节不会改变include?
测试。 Rails不会重新加载本书中的章节。因此,它不会知道书中不再存在这一章。
请注意,include?
(在Enumerable
/ Array
个对象上定义,但未直接在ActiveRelation
对象上实现)将自动导致Rails强制转换{{1}对象ActiveRelation
到数组。因此,book.chapters
将首先获取章节数组,然后检查该章节是否包含在数组中。
显式调用include?
(在任何reload
对象上)强制rails重新加载该特定对象,以便丢弃书中章节的缓存,并重新加载实际章节。 / p>
ActiveRecord
即可。reload
告诉Rails急切加载而不是延迟加载,例如。 includes
。这意味着Rails将在加载书籍的同时加载所有章节。要删除章节,同时确保book = Book.includes(:chapters).first
是最新的,您可以致电book.chapters
或books.chapters.delete(book.chapters.last)
。使用此方法,Rails不需要再次查询数据库以确定它不再在集合中。