一次循环通过2个模型对象

时间:2011-07-11 21:42:01

标签: ruby-on-rails ruby iterator mysql2

我有一个用户对象,我通过简单的调用公开了这个对象:

@users = User.all

我在使用自定义SQL生成结果的地方也有一些更昂贵的查询。

@comment_counts = User.received_comment_counts

此调用和其他类似的调用将返回按ID排序的列表中每个用户一个元素的对象。

在我看来,我想同时遍历用户和comment_counts对象。例如:

for user, comment_count in @users, @comment_counts do
end

我无法弄清楚如何做到这一点。我似乎也无法弄清楚如何从@comment_counts结果中获取单个记录而不通过@ comment_counts.each运行它

是否有某种方法可以为每个lits对象构建一个迭代器,将它们转储到while循环中并在循环的每次传递中单独执行迭代器?另外,如果您可以回答这个问题,我可以在哪里学习逐步浏览列表中的列表。

3 个答案:

答案 0 :(得分:5)

这样的事情对你有用:

@users.zip(@comment_counts).each do |user, comments_count|
  # Do something
end

我从未在Ruby中遇到迭代器的手动操作,更不用说它无法完成。像这样的代码可能会很混乱,所以我可能更喜欢更优雅的解决方案。

答案 1 :(得分:3)

假设数组具有相同的值:

在您的控制器中:

@users = User.all
@comments = Comment.all

在您看来。

<% @users.each_with_index do |user, i |%>
    <% debug user %>
    <% debug @comments[i] %>
<% end %>

然后,如果您不知道数组是否具有相同数量的对象,您可以检查@comments上是否存在值。

答案 2 :(得分:0)

这并不明显,因为您的数据需要进行一些重组。 comment_count显然属于User的实例,应该反映这一点,以便只需要在一个集合(User s)上循环。我可以想到两种可能的方法来实现这一目标:

  1. Eager loading仅适用于相关模型,而不是这里的情况。比如说,您的每个用户都有comments,因此撰写User.includes(:comments).all会向所有用户返回他们的评论,并且只会执行2次查询来获取数据。

  2. 要计算每个用户的评论,您只需使用counter_cache (clickable)即可。然后,您将在users表中再添加一个字段,用于缓存用户拥有的注释数量。同样,仅适用于关联的Comment