检查 ActiveRecord 集合中是否有记录的正确方法

Pio*_*ioz 5 activerecord ruby-on-rails

在我看来,我有这样的代码:

<% if @posts.any? %>
  <% @posts.each do |post| %>
    ...
  <% end %>
<% else %>
  <p>No posts found</p>
<% end %>
Run Code Online (Sandbox Code Playgroud)

这会在我的控制台日志中生成:

...
Post Exists (1.4ms)  SELECT  1 AS one FROM `posts` LIMIT 1 OFFSET 0
...
Post Load (1.1ms)  SELECT  `posts`.* FROM `posts` LIMIT 50 OFFSET 0
...
Run Code Online (Sandbox Code Playgroud)

所以这会触发对我的数据库的 2 个查询。如果我以这种方式改变视图

<% unless @posts.blank? %>
  <% @posts.each do |post| %>
    ...
  <% end %>
<% else %>
  <p>No posts found</p>
<% end %>
Run Code Online (Sandbox Code Playgroud)

只会触发一个查询:

...
Post Load (1.1ms)  SELECT  `posts`.* FROM `posts` LIMIT 50 OFFSET 0
...
Run Code Online (Sandbox Code Playgroud)

如果我使用@posts.exists?or@posts.empty?或 则@posts.any?执行两个查询,如果我使用@posts.blank?or 则@posts.present?仅执行一个查询。

所以我的问题是:有一种最佳实践来检查集合是否为空?什么时候应该使用exists?empty?any?和?present?blank?

Rit*_*jan 3

存在吗?应该使用,因为它是最快的。

@post.blank? would retrieve all the post and count them.

!@post.present? would retrieve all the post and count them.

@post.empty? would retrieve the count of post.
Run Code Online (Sandbox Code Playgroud)

空白?,现在?,空?如果您有预加载的记录,则很好用。

@post.any? would be exactly the same as the previous option.
Run Code Online (Sandbox Code Playgroud)

任何?检索关系中的记录(除非它们已预加载),将它们表示为数组,然后调用。存在于何处?始终查询数据库,从不依赖于预加载的记录,并且仅检索一条记录,这使得该方法比任何方法都快?

@post.exists? would retrieve the first post. That makes this approach fastest among those five.
Run Code Online (Sandbox Code Playgroud)