Ruby on rails CollectionAssociation.包括吗?检查数据库中是否存在记录?
我一直在阅读Rails 3-Way,并且正在检查收集关联的行为。包括? 根据书中的描述: 检查所提供的记录是否存在于关联中 集合,并且它仍然存在于基础数据库中 桌子 我做了两个测试来检查DB是否被检查,但看起来它没有被检查Ruby on rails CollectionAssociation.包括吗?检查数据库中是否存在记录?,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我一直在阅读Rails 3-Way,并且正在检查收集关联的行为。包括? 根据书中的描述: 检查所提供的记录是否存在于关联中 集合,并且它仍然存在于基础数据库中 桌子 我做了两个测试来检查DB是否被检查,但看起来它没有被检查 > book = Book.first => #<Book id: 1, title: "Programming Ruby"... > last_chapter = book.chapters.last => #<Chapter id: 2
> 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
>book=book.first
=>#最后一章=book.chapters.last
=>#b.章节。包括?(最后一章)
=>正确
>最后一章
从“章节”中删除,其中“章节”。“id”=?[“id”,2]]
=>#b.章节。包括?(最后一章)
=>正确
>重新加载
=>[#b.章节。包括?(最后一章)
=>错误
我检查了源代码,发现一行load\u target if options[:finder\u sql]
,它似乎有条件地加载记录
您知道何时访问数据库以检查数据库中是否存在记录吗?Rails使用延迟加载和记忆 这意味着
b.chapters
在第一次调用getter之前不会加载任何章节
之后,由于记忆化,销毁章节不会更改include?
测试。Rails不会重新加载书中的章节。因此,它不会知道该章节不再存在于书中
请注意,包含?
(在可枚举的/数组对象上定义,但不直接在活动关系对象上实现)将自动使Rails将ActiveRelation
对象book.chapters
强制转换为数组。因此,include?
将首先获取章节数组,然后检查该章节是否包含在数组中
显式调用reload
(在任何ActiveRecord
对象上)会强制rails重新加载该特定对象,从而丢弃书中章节的缓存,并重新加载实际章节
- 您不能关闭备忘录功能,除非在需要重新加载的任何地方调用
reload
- 您可以使用
includes
,例如book=book.includes(:chapters)。首先,告诉Rails立即加载而不是延迟加载。这意味着Rails将在加载书籍的同时加载所有章节
要删除章节,同时确保book.chapters
是最新的,您可以调用books.chapters.delete(book.chapters.last)
或books.chapter\u id.delete(book.chapter\u id.last)
。使用此方法,Rails无需再次查询数据库即可知道它已不在集合中。感谢您的深刻回答。这确实有助于理解许多事情。但在哪种情况下,include?
方法会影响DB?include?
(或任何其他作用于数组的方法)仍然存在问题当且仅当章节
尚未加载时点击DB。章节
由于延迟加载,直到您第一次调用它时才会加载。当我说“当您第一次调用getter时”,我的意思是调用book.chapters
,这是一种“获取”的方法章节。如果未加载集合,它将运行一个db查询,该查询仅检查对象的存在,而不是加载整个集合(类似于未加载集合时执行select count(*)的大小)哦,是的,就是这样。但是,如果集合已经加载,它只使用数组。但是last\u chapter=book.chapters.last
已经加载了集合数组。因此Rails在这种情况下使用数组。