我有一些简单查询的代码,我试图通过将它们压缩到一个查询中来对其进行优化。但是我不知道如何。
posts = Post.where(category: "article")
num_posts = posts.count
first_post = posts.first
posts_with_updated_name = posts.map { |post| post[:name] = "UPDATE_" + post[:name] }
我希望有一个查询,该查询将在第一行执行,然后 posts 是一个数组,可以在该数组上执行第2、3和4行的操作。我得到的是,我有3个独立的查询。知道如何将其优化为单个查询吗?
LE:您可以假设num_posts
,first_post
和posts_with_updated_name
只是我以后需要使用的变量
答案 0 :(得分:2)
由于将ActiveRecord::Relation
对象转换为Array
可能会为大型数据库消耗大量内存(甚至可能耗尽内存),因此我将执行以下操作,但仍会使用(2 +批数)SQL查询,但您的应用程序可以长期扩展。
posts = Post.where(category: "article")
num_posts = posts.count
first_post = posts.first
# || is a PostgreSQL operator for string concatenation
# if you are using MySQL check out CONCAT instead
posts_with_updated_name = posts.select('posts.*', "'UPDATE_' || name AS updated_name")
# example usage
posts_with_updated_name.find_each do |post|
puts post.id
puts post.name
puts post.updated_name
end
# example output:
# 6
# 'Spider Man is Back'
# 'UPDATE_Spider Man is Back'
# 84
# 'Hello World'
# 'UPDATE_Hello World'
我不会将“更新后的名称”存储到变量中,而是仅按需添加/添加字符串,如下所示:
posts = Post.where(category: "article")
num_posts = posts.count
first_post = posts.first
# somewhere in your code where you are actually already gonna be looping over `posts`
posts.find_each do |post|
updated_name = "UPDATE_#{post.name}'"
# do something here about updated name
end
或者...如果此“更新名称”值是整个应用程序的永久逻辑,则只需在模型中编写一个方法:
app / models / post.rb
class Post < ApplicationRecord
# ...
def updated_name
"UPDATE_#{name}"
end
end
然后在代码中,您只需执行以下操作,而无需设置“更新名称”的值,
posts = Post.where(category: "article")
num_posts = posts.count
first_post = posts.first
# example:
puts first_post.updated_name
# => 'UPDATE_Hello World'
答案 1 :(得分:1)
我不确定我是否很好地理解了您的问题,但是我认为您想将ActiveRecord集合转换为数组?如果是这样,您可以使用posts = Post.where(category: "article").to_a