ヘルパーメソッド解説＋@

ヘルパーメソッドを勉強する中、疑問点が生じましたので、備忘録としてアップします。同じ事を思っている方の参考になったら幸いです。

いきなり、問題文をあげますがこの問題で感じた疑問点を解説します。

#問題

```app/views/tweets/index.html.erb
<%= form_with(url: search_tweets_path, local: true, method: :get, class: "search-form") do |form| %>
  <%= form.text_field :keyword, placeholder: "投稿を検索する", class: "search-input" %>
  <%= form.submit "検索", class: "search-btn" %>
<% end %>
<div class="contents row">
  <% @tweets.each do |tweet| %>
    <%= render partial: "tweet", locals: { tweet: tweet } %>
  <% end %>
</div>
```
内の

```
  <% @tweets.each do |tweet| %>
    <%= render partial: "tweet", locals: { tweet: tweet } %>
  <% end %>
```
部分をHelperメソッドを用いてください。

#答え

先に答えを書きます。

```app/views/tweets/index.html.erb
<%= form_with(url: search_tweets_path, local: true, method: :get, class: "search-form") do |form| %>
  <%= form.text_field :keyword, placeholder: "投稿を検索する", class: "search-input" %>
  <%= form.submit "検索", class: "search-btn" %>
<% end %>
<div class="contents row">
   <%= tweet_lists(@tweets) %>
</div>
```

```app/helpers/tweets_helper.rb
module TweetsHelper
  def tweet_lists(tweets)
    html = ''
    tweets.each do |tweet|
      html += render(partial: 'tweet',locals: { tweet: tweet })
    end
    return raw(html)
  end
end
```

#解説
Helperメソッドの呼び出しは　tweet_list　をメソッドとして呼び出しています。
そのため、def以下の（tweets）が（@tweets）に置き換わります。

```
 tweets.each do |tweet|
```
は

```
@tweets.each do |tweet| 
```
となり＠tweetの値をtweetに展開します。

html = ''は　htmlの中に何も入っていないという事を表します。

```
html += render(partial: 'tweet',locals: { tweet: tweet })
```
html＋＝〜　は　html＝html＋〜　と表せますので

```
html = html＋render(partial: 'tweet',locals: { tweet: tweet })
```
となり、
eachの回数だけ、render(partial: 'tweet',locals: { tweet: tweet })が足されていくという構文となります。

```
each 1回目：
html　＝　””（なし）+render(partial: 'tweet',locals: { tweet: tweet })
each 2回目：
html　＝　””（なし）+render(partial: 'tweet',locals: { tweet: tweet })
                +render(partial: 'tweet',locals: { tweet: tweet })
each 3回目：
html　＝　””（なし）+render(partial: 'tweet',locals: { tweet: tweet })
                +render(partial: 'tweet',locals: { tweet: tweet })
                +render(partial: 'tweet',locals: { tweet: tweet })
each ４回目：…
```
以上のように＠tweetsの中身の数だけ（ツイートの数だけ）、処理が加算されていきます。

ここまできて、疑問点が浮かび上がりました。

#疑問点
１
tweet_listsがヘルパーメソッとなり、ndex.html.erbとtweets_helper.rbを結び付けておりますが、index.html.erbだけで判断した場合、 メソッドの種類はたくさんありますので、　<%= tweet_lists(@tweets) %>のtweet_listsがヘルパーメソッドであると判断するのは難しいのではないか。Helperメソッドと判断する根拠は他にあるのだろうか。

２
tweets_helper.rbの中に

```
html += render(partial: 'tweet',locals: { tweet: tweet })
```
レンダーメソッドがあります。index.html.erb内にHelperメソッドを使い、tweets_helper.rbを呼び出し、さらにtweets_helper.rb内でrenderメソッドを用いて_tweet.html.erbを呼び出しています。

つまりこのような3重の構造になっております。
index.html.erb
 ↑　tweets_helper.rb
　　↑_　tweet.html.erb

可読性をあげるためにHelperメソッドを用いましたが、ファイル間を跨ぐ回数が増えて可読性を下げているのではないか。逆にHelperメソッドを使わない方がわかりやすいのではないか。

参考

```_tweet.html.erb
    <div class="content_post" style="background-image: url(<%= tweet.image %>);">
      <div class="more">
        <span><%= image_tag 'arrow_top.png' %></span>
        <ul class="more_list">
          <li>
            <%= link_to '詳細', tweet_path(tweet.id), method: :get %>
          </li>
          <% if user_signed_in? && current_user.id == tweet.user_id %>
            <li>
              <%= link_to '編集', edit_tweet_path(tweet.id), method: :get %>
            </li>
            <li>
              <%= link_to '削除', tweet_path(tweet.id), method: :delete %>
            </li>
          <% end %>
        </ul>
      </div>
      <p><%= tweet.text %></p>
      <span class="name">
        <a href="/users/<%= tweet.user.id %>">
          <span>投稿者</span><%= tweet.user.nickname %>
        </a>
      </span>
    </div>
```

#結論
##1: ヘルパーメソッドかの判断は経験と慣れです
確かに、index.html.erbからみた場合、 <%= tweet_lists(@tweets) %>だけで、tweet_listsがヘルパーメソッドかを判断するのは難しいです。
binding.pryして値を確認する等のやり方はあるそうですが、基本的には慣れていくうちにヘルパーメソッドかの判断ができるようになるそうです。

#2-1: Helperメソッドは再利用可能
結論的にはHelperメソッドを使うことは有効です。今回、index.html.erb内で

```
  <% @tweets.each do |tweet| %>
    <%= render partial: "tweet", locals: { tweet: tweet } %>
  <% end %>
```
上記コードにHelperメソッドを使用しましたが、その他のファイルでも　tweet_lists　を使えば上記を呼び出すことができます。twees.each do　を別のファイルで複数回使う際にはHelperメソッドとした方が良いでしょう。

#2-2: ２重構造までが読みやすいコード
今回はHelperメソッドの中にrenderメソッドが入っていましたが、実際にはこうしたHelperの中でrenderするような３重構造はほとんど取らないそうです。ただ、可読性を考慮すると、２重構造までを限度と考えることが良いでしょう。そのため、Helperメソッドの中にrenderメソッドを入れることは好ましくないと言えます。


以上