0

我有以下Rails代码,其中它技术上最多做两个查询,但由于某种原因,控制台显示三个不同的查询,如下面的屏幕截图所示。我的问题是为什么它会在没有必要时运行SELECT "pages".* FROM "pages"查询?为什么Rails会运行额外的不必要查询?

查询

page = Page.includes(:page_roles) 
    page.where(is_deleted: false).index_by(&:name) 
    page_results = {} 
    page.each do |entry| 
     result_entry = entry.as_json; 
     result_entry['page_roles'] = entry.page_roles 
     page_results[entry.name] = result_entry 
    end 

控制台输出

Page Load (0.0ms) SELECT "pages".* FROM "pages" WHERE "pages"."is_deleted" = $1 [["is_deleted", false]] 
PageRole Load (0.5ms) SELECT "page_roles".* FROM "page_roles" WHERE "page_roles"."page_id" IN (1, 2, 3, 4) 
Page Load (0.5ms) SELECT "pages".* FROM "pages" 
CACHE (0.0ms) SELECT "page_roles".* FROM "page_roles" WHERE "page_roles"."page_id" IN (1, 2, 3, 4) 
Completed 200 OK in 117ms (Views: 16.9ms | ActiveRecord: 17.0ms) 

Screenshot of the console

+2

请从控制台输入代码,无法辨认。 – Iceman

+0

对不起,更新了问题 –

+0

它实际上是4个查询。 –

回答

1

这里的原因:

page = Page.includes(:page_roles) 
page.where(is_deleted: false).index_by(&:name) # your first two queries (pages + page_roles). 
               # query is triggered by index_by (method of enumerable, not activerecord) and result is ignored 
               # as it's not saved anywhere. 

page_results = {} 
page.each do |entry| # your second two queries. Note that this one doesn't use `is_deleted: false` filter. 
        # page_roles query is served from cache as it didn't change. 
    result_entry = entry.as_json; 
    result_entry['page_roles'] = entry.page_roles 
    page_results[entry.name] = result_entry 
end 
+0

岂不'page'仍然有以前附加方法?例如,在执行'page.each'时,'page'变量仍然不包含先前附加的方法'page.includes(:page_roles)'和'page.where(is_deleted:false).index_by(&:name )'? –

+0

'includes' - 是的(因为它被保存到'pages')。另一个 - 不。 –

0

我相信这是因为你已经得到了page.where查询将仍然使用ActiveRecord的查询界面在页表上,而不是使用Acti存储为page的veRecord集合。

1

那是因为第一项任务。您可以做空做了这一切:

page_results = 
    Page 
    .includes(:page_roles) 
    .where(is_deleted: false) 
    .group_by(&:name) 
+0

我这样做是因为,如果不尝试从结果项中访问'page_roles'属性,那么该属性将保持未设置状态。 –

+0

我看到这个问题,你可以使用一个串行然后https://github.com/rails-api/active_model_serializers/blob/master/docs/general/getting_started.md –

相关问题