Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails CollectionAssociation.包括吗?检查数据库中是否存在记录?_Ruby On Rails_Activerecord - Fatal编程技术网

Ruby on rails CollectionAssociation.包括吗?检查数据库中是否存在记录?

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

我一直在阅读Rails 3-Way,并且正在检查收集关联的行为。包括?

根据书中的描述:

检查所提供的记录是否存在于关联中 集合,并且它仍然存在于基础数据库中 桌子

我做了两个测试来检查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 
>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在这种情况下使用数组。