Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.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
Sql 通过联接表过滤器进行Rails预加载查询_Sql_Ruby On Rails_Optimization_Eager Loading - Fatal编程技术网

Sql 通过联接表过滤器进行Rails预加载查询

Sql 通过联接表过滤器进行Rails预加载查询,sql,ruby-on-rails,optimization,eager-loading,Sql,Ruby On Rails,Optimization,Eager Loading,我正在查询一堆由人们撰写和收到的信件。我通过联接表将信件表与人员表相关联,联接表使用persontype标识符(0=创建者,1=收件人)确定此人是相关信件的创建者还是收件人 我的问题是:我在一个视图中一次显示50封信件,其中包含日期、创建者、收件人和博物馆收藏等信息。页面加载速度非常慢,因为尽管我已经知道了如何“包含”集合,这样就不会对显示的每封信运行查询,但我无法为创建者和接收者执行此操作。如果我只是显示“人物”,我也可以进行包含,但由于我是按人物的角色过滤人物,rails会对视图中的每个字母

我正在查询一堆由人们撰写和收到的信件。我通过联接表将信件表与人员表相关联,联接表使用persontype标识符(0=创建者,1=收件人)确定此人是相关信件的创建者还是收件人

我的问题是:我在一个视图中一次显示50封信件,其中包含日期、创建者、收件人和博物馆收藏等信息。页面加载速度非常慢,因为尽管我已经知道了如何“包含”集合,这样就不会对显示的每封信运行查询,但我无法为创建者和接收者执行此操作。如果我只是显示“人物”,我也可以进行包含,但由于我是按人物的角色过滤人物,rails会对视图中的每个字母运行多个查询,这大约需要6000毫秒。如果没有创建者和接收者,视图将在大约250毫秒内加载

以下是我的模型的基本知识:

class ArchiveObject < ActiveRecord::Base
    has_many :archive_object_people
    has_many :people, :through => :archive_object_people

class ArchiveObjectPerson < ActiveRecord::Base
    belongs_to :archive_object
    belongs_to :person

class Person < ActiveRecord::Base
    has_many :archive_object_people
    has_many :archive_objects, :through => :archive_object_people
我希望以相同的方式预加载创建者和收件人,例如,包括信件的位置,这样我就可以遍历每个信件并显示letter.title、letter.creators、letter.collection等,而无需运行几十次查询。例如:ArchiveObject.includes(:集合,:创建者)

到目前为止我一直在尝试的事情。在获取收件人/创建者时,所有这些人都将运行另一个查询,尽管他们在查看一般“人员”时可能不会运行另一个查询:

我还开始阅读关于重新定义has_许多并使用一个条件来只提取创建者或接收者的内容,但实际上我需要两个关联,在这种情况下:a has_许多创建者和a has_许多接收者。我不知道如何设置,但如果有人有任何想法,那将是rad


谢谢你能给我的任何帮助或建议!我很想弄明白这一点,这样我就有了一个超级快速高效的网站

好的。这花了我几个小时,但我想出来了

我删除了所有自定义实用程序方法,并重写了一些具有多种类型的内容

class ArchiveObject < ActiveRecord::Base
  has_many :archive_object_people
  has_many :people, :through => :archive_object_people

  has_many :creators, -> { where "archive_object_people.persontype = '0'" },
           :through => :archive_object_people
           :source => :person
  has_many :recipients, -> { where "archive_object_people.persontype = '1'" },
           :through => :archive_object_people,
           :source => :person
以前我可以使用自定义方法获取这些信息,但现在使用includes,您可以预加载它们,这样它就可以预先运行大量查询,然后在提取每个字母的信息时不需要再次运行它

我希望这能帮助其他人。注意:源代码中有很多描述是为了:person,而不是:people,这给我带来了一些暂时的痛苦

ArchiveObject.joins(:people).where("archive_object_people.persontype = '1'").preload(:people)

ArchiveObject.includes(:people, :archive_object_people).first.recipients

ArchiveObject.includes(:recipients)  => raises an exception
class ArchiveObject < ActiveRecord::Base
  has_many :archive_object_people
  has_many :people, :through => :archive_object_people

  has_many :creators, -> { where "archive_object_people.persontype = '0'" },
           :through => :archive_object_people
           :source => :person
  has_many :recipients, -> { where "archive_object_people.persontype = '1'" },
           :through => :archive_object_people,
           :source => :person
test = ArchiveObject.includes(:people, :creators, :recipients)
test.first.people  # => list of all people on first object
test.first.creators # => list of all people who are creators on first object
test.first.recipients # => all people who are recipients