如何使这个嵌套迭代器检查更加干燥和高效?

时间:2017-03-10 23:34:13

标签: ruby-on-rails ruby ruby-on-rails-5

我有dummy projects to watch,所以我有parent

每个@commit都有has_many :diffs,其中包含一个字符串。

我遇到的问题是,我需要能够快速检查属于该@diffs = @commit.diffs的每个diff的{​​{1}},看看它是否满足某些条件(即即.body)。如果是,我想保存/使用body

我实现它的方式是:

diff

这似乎不优雅。我怎样才能让它变得干爽,高效和清洁?

我也想从我的观点中看出这一点,然后进入帮手/装饰者或其他什么。

2 个答案:

答案 0 :(得分:0)

一般来说,说这种逻辑不应该在视图中是正确的。我建议使用装饰器。看看Draper gem来帮助解决这个问题。以下是如何使用Draper执行此操作的示例。

# In you controller
class YourController < ApplicationController
  # ...
  @diffs = @commit.diffs.decorate # after adding draper, add `.decorate` to this line in the controller
  # ...
end

# In a Draper decorator
class DiffDecorator < Draper::CollectionDecorator
  def get_some_subset_of_the_diffs
    decorated_collection.select { |diff| diff.body.include? (line_count - 3).to_s }
  end
end

# Your view
<% @diffs.get_some_subset_of_the_diffs.each do |diff| %>
  <% diff.body.lines.each do |dl| %>

  <% end %>
<% end %>

另外,您想用diff.body.include? (line_count - 3).to_s完成什么?有些情况可能会运行,但这可能不会执行您想要的逻辑。是否应该检测少于3行变化的差异?

答案 1 :(得分:0)

为什么不将大部分逻辑移到模型中?假设您拥有CommitDiff模型,则可以:

# NOTE: you'll want to change the name "affected" to something that is more meaningful. I don't quite understand what matching on the line count is meant to do here.

class Commit
  def affected_diffs(line_count)
    # the `@diffs ||=` part is optional memoization (read more here: http://gavinmiller.io/2013/basics-of-ruby-memoization/)
    # it can be helpful for performance if you call this method multiple times in your view
    @diffs ||= diffs.select { |diff| diff.affected?(line_count) }
  end
end

class Diff
  # no need to rewrite this logic if you also choose to use it elsewhere
  def affected?(line_count)
    body.include? (line_count - 3).to_s
  end
end

# then in your view
<% @commit.affected_diffs(line_count).each do |diff| %>
  <%# work with each diff %>
<% end %>