这是我的代码,它提供了N +1查询。
class User < ApplicationRecord
has_many_attached :resumes, dependent: :destroy
has_many_attached :cover_letters, dependent: :destroy
end
class ResumesController < ApplicationController
def new
@user = User.includes(resumes_attachments: :blob).find(params[:user_id])
end
def create
@user = User.includes(resumes_attachments: :blob).find(params[:user_id])
if @user.resumes.attach(params[:user][:resume])
redirect_to new_user_resume_path(@user)
else
render :new
end
end
end
我已经注解掉了视图中的所有内容,以确保那里没有发生任何事情。Bullet gem只在创建操作失败和render :new
被触发时才抱怨。如果创建操作成功,Bullet gem不会给出任何错误。
但是当我检查服务器日志时,ActiveStorage::Blob
被调用了这么多次。我错过了什么?我使用的是Rails 6。
- 更新日期:**
下面是我的日志。
↳ app/controllers/resumes_controller.rb:17:in `create'
ActiveStorage::Blob Load (0.2ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", "13e9e539-8c45-473f-b849-9e459646a1a1"], ["LIMIT", 1]]
↳ app/controllers/resumes_controller.rb:17:in `create'
ActiveStorage::Blob Load (0.3ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", "2581e71d-98e3-4edc-afb8-310e699dde00"], ["LIMIT", 1]]
↳ app/controllers/resumes_controller.rb:17:in `create'
ActiveStorage::Blob Load (0.2ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", "59ad2a58-dafe-4983-83d0-ce27ba37ff01"], ["LIMIT", 1]]
↳ app/controllers/resumes_controller.rb:17:in `create'
ActiveStorage::Blob Load (0.2ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", "6f3431c2-8bb7-4348-a9d9-d36a4e8ea6bb"], ["LIMIT", 1]]
↳ app/controllers/resumes_controller.rb:17:in `create'
ActiveStorage::Blob Load (0.5ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", "ac925113-8f42-4d12-aa04-842a812e57ab"], ["LIMIT", 1]]
↳ app/controllers/resumes_controller.rb:17:in `create'
ActiveStorage::Blob Load (0.2ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", "bd753376-408b-497b-b4f9-8cdd4c85c23e"], ["LIMIT", 1]]
↳ app/controllers/resumes_controller.rb:17:in `create'
ActiveStorage::Blob Load (0.2ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", "d48b3658-bb81-472b-b9b9-8da341a55ab6"], ["LIMIT", 1]]
↳ app/controllers/resumes_controller.rb:17:in `create'
ActiveStorage::Blob Load (0.2ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", "e098a866-e14d-4477-8f4d-bd48389d0831"], ["LIMIT", 1]]
↳ app/controllers/resumes_controller.rb:17:in `create'
- 更新2**
我也试过User.with_attached_resumes.find(id)
,但还是同样的问题
- 更新3**
下面是我的代码从new.html.erb
页
<%= form_with model: @user, url: user_resumes_path(@user), method: :post, local: true do |f| %>
<div class='row'>
<div class='col-md-12 col-sm-12'>
<div class='statistic-item'>
<%= f.file_field :resume, class: 'form-control file-field' %>
</div>
</div>
</div>
<div class='row mrg-top-30'>
<div class='col-md-12 col-sm-12'>
<div class='form-group text-center'>
<%= f.submit 'Upload Resume', class: 'btn btn-primary theme-bg' %>
</div>
</div>
</div>
<% end %>
解决方案
我设法解决了这个问题,但我不知道它为什么工作。基本上我必须包括cover_letters
以及然后N +1查询得到解决。这是非常奇怪的,我必须包括cover_letters
当我试图附加只是简历。以下是我的工作代码create
行动
@user = User.includes(resumes_attachments: :blob, cover_letters_attachments: :blob).find(params[:user_id])
或
@user = User.with_attached_resumes.with_attached_cover_letters.find(params[:user_id])
如果有人对这种行为有解释,请让我知道。谢谢
1条答案
按热度按时间6mw9ycah1#
最后,我找出了
active_storage
应用程序中N + 1查询的主要原因所以在挖掘了一段时间之后,我意识到我们的应用程序正在使用
UUID
作为所有主键,然后我检查了active_storage
的迁移文件,查看UUID
是如何设置的,在那里我发现了一行错误的代码。这是旧代码
这是固定代码
修复迁移后,我的代码按预期工作,我没有得到N + 1查询,我不必包括
cover_letters
黑客来修复N + 1
查询。或
以下是
active_storage
的最终迁移文件