2017-03-10 10 views
0

私には@commitがあります。has_many :diffsですので、私は@diffs = @commit.diffsです。このネストされたイテレーターチェックをDRYと効率的にするにはどうすればよいですか?

diffには、文字列を含む.bodyがあります。

私はに実行している問題は、私はすぐにそれが(すなわち、すなわちbody.include? (line_count - 3).to_s)いくつかの条件を満たしているかどうかを確認するためにそのcommitに属しているすべてのdiffbodyをチェックできるようにする必要があるということです。もしそうなら、私はそれを保存/使用したいです。diff

私はそれを実装している方法は、これを行うことである。

<% @diffs.each do |diff| %> 
    <% if diff.body.include? (line_count - 3).to_s %> 
     <% diff.body.lines.each do |dl| %> 

     <% end %> 
    <% end %> 
    <% end %> 

洗練思われます。どのようにこれをより乾燥し、効率的できれいにすることができますか?

私はこれを私の見解から外して、ヘルパー/デコレータなどに移動したいと思います。

+0

は 'ほとんど何かにto_s'を呼び出すと、あなたが戻って文字列を取得する保証、および任意の文字列は、常に論理的に真です。その状態は決して発火しません。 – tadman

答えて

0

一般的に、そのようなロジックはビューに含まれてはならないと言うのは間違いありません。私はこのためにデコレータを使用することをお勧めしたいと思います。これを手助けするために、Draperの宝石を見てください。以下は、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行未満の差分が検出されたとしますか?

+0

Re:あなたの質問、いいえ....そのロジックは 'line.count - 3'の値が含まれているかどうかを見るために' diff.body'の文字列値をチェックしています。これは整数を返します。 '.to_s'と同じ文字列です。 – marcamillion

+0

その場合、あなたは 'select'でこれを達成することができます。これを反映するために私の答えを更新しました。 – Glyoko

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 %> 
関連する問題