0

我正在为数组上的简单实现而苦苦挣扎。我已经阅读了各种类方法,但想确保我找到了一个优雅的解决方案。

我基本上想知道给定系统中有多少特定标签的原始计数。所以如果一个标签belongs_to :person和一个人可以has_many :tags

我想知道如何才能呈现有多少人拥有“蓝色”标签的原始总数(如果有“蓝色”、“红色”、“绿色”和“橙色”标签)。这是我正在追求的道路,但我认为代码很快就会开始闻起来..

<% @people.each do |person| %>
    <% if person.tags.include?('blue') %>
     <%= person.id %> # this is where I get stuck
    <% end %>
<% end %>

因此,我正在显示系统中所有具有蓝色标签的人的对象,但现在我需要对这些人求和以获得原始计数。而且我需要在视图中渲染几次,每种颜色一次(希望只在 中切换参数include)。

这开始有气味,因为它不会变得非常干燥。这应该是一个类方法吗?我应该将返回的人转换回数组并调用.count吗?

我最终可以得到原始数字,但我对这里的最佳实践有点迷失了。

- -更新 - -

这是我迄今为止根据 Gene 的反馈更新的解决方案。

现在它更干净了,但现在我想知道性能,因为它看起来很慢。

我有一个辅助方法-

def tag_count_for_person(tags_name)
    @people.count {|person| person.tags.include?('tags_name') }
end 

并为我需要在视图中呈现的任何标签调用此方法。

<div class="well span4">
<%= tag_count_for_person("green") %>
</div>
<div class="well span4">
<%= tag_count_for_person("blue") %>
</div>
<div class="well span4">
<%= tag_count_for_person("red") %>
</div>
<div class="well span4">
<%= tag_count_for_person("hungry") %>
</div>

我相信它仍然闻起来。每次我想在视图中呈现不同的标签时,我不需要调用这个方法吗?看来代价不菲。但是我没有添加我想要正确渲染的不同标签的灵活性?我觉得我离得更近了。

4

2 回答 2

1

但我认为代码很快就会开始闻起来..

嗯,它已经闻起来了。这种逻辑不属于视图。您最好将其放入控制器或模型中。这是一个例子。

colors = ['blue', 'red', 'green']

@people = ...

@people_count = {} # here we'll store counts by color
@people.each do |person|
  colors.each do |col|
    if person.tags.include?(col)
      # increment count
      @people_count[col] ||= 0
      @people_count[col] += 1
    end
  end
end

另一种方法,更优雅

colors = ['blue', 'red', 'green']
@people_count = colors.each_with_object({}) do |color, memo|
  memo[color] = @people.count{|p| p.tags.include?(color)}
end

然后,在视图中

<%= @people_count['blue'] %>
于 2013-05-30T00:10:10.460 回答
0

好吧,我同意@Sergio Tulenntsev,但如果你只需要数蓝色,你可以用一种不会太难闻的方式来做:

<%= @people.count {|person| person.tags.include?('blue') } %>

将产生具有蓝色标签的整数数量的人。把它放在一个辅助函数中会更干净一些。

于 2013-05-30T00:20:47.333 回答