【问题标题】:Is it better to use select or loop through an array of records in Rails?在 Rails 中使用选择或循环记录数组更好吗?
【发布时间】:2019-07-02 08:57:12
【问题描述】:

我的目标是以最简洁、最有效的方式编写下面的查询,并尽量减少对数据库的影响。提前感谢任何指导。

我检索到了一些属于user 的记录,如下所示:

english_shows = @user.shows.where(language: 'english')

假设shows 属于不同的categories(使用外键),如下所示:

<ActiveRecord::Relation [
  <Show id: 1, category_id: 1, title: 'Rick and Morty'>,
  <Show id: 2, category_id: 2, title: 'Black Mirror'>,
  <Show id: 3, category_id: 3, title: 'Stranger Things'>,
  <Show id: 4, category_id: 3, title: 'Game of Thrones'>,
  ...
]

如果我想获取每个类别的shows 的标题,我知道我可以像这样使用selectwhere 可以做同样的事情,但这会导致额外的数据库调用。[编辑]实际上,两者都会访问数据库两次)。 p>

# Using select
cartoons = english_shows.select { |show| show.category_id == Category.find_by(name: 'cartoon').id}.pluck(:title)

# Using where
cartoons = english_shows.where(category_id: Category.find_by(name: 'cartoon').id)pluck(:title)

但是,select 方法仍然会导致多行长代码(在我的实际用例中,我有更多的类别类型)。循环遍历这样的记录是否更干净(取自此 SO answer)?

cartoons, science_fiction, fantasy = [], [], []
@cartoon_id = Category.find_by(name: 'cartoon')
@science_fiction_id = Category.find_by(name: 'cartoon')
@fantasy_id = Category.find_by(name: 'cartoon')

english_shows.each do |show|
  cartoons << show if show.category_id == @cartoon_id
  science_fiction << show if show.category_id == @science_fiction_id
  fantasy << show if show.category_id == @fantasy_id
end

【问题讨论】:

  • "这只会访问数据库一次"select 从哪里获取记录? english_shows 已经是数组还是关系了?
  • 我猜这种理解是错误的——当我之前尝试过时,似乎select 只是使用了变量中的内容,但刚刚尝试它我意识到它仍然会命中数据库以获取值english_shows 再次。在这种情况下,我的问题仍然存在 - 是循环遍历,使用select,还是使用where
  • where 通常会导致执行速度更快 - select 将遍历集合中的每条记录并对其应用条件 - where 将在一个事务中执行所有这些操作

标签: ruby-on-rails database loops select


【解决方案1】:

试试这个:

english_shows
  .joins(:category)
  .select('shows.*, categories.name as category')
  .group_by(&:category)

【讨论】:

  • 这很好用,我可以看到这是一个数据库调用。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-16
  • 2011-02-20
  • 2012-02-26
  • 1970-01-01
相关资源
最近更新 更多