読者です 読者をやめる 読者になる 読者になる

Ruby on Rails と歩む我が人生

Railsプログラマを目指す漢のRailsとの歩みの記録

Railsでインスタンス変数が生成するコードがつらい話

Ruby Rails プログラミング

はじめに

RubyRailsではわりとコードが省略して書けるため、初学者(ぼく)のみなさんはそれは苦しめられていると思います。 Scaffoldで生成されるコードとかもうほんと一言で言い表すと「挫折」って感じですね!

環境作成

こちらの手順で作成した環境となります!

qiita.com

つらいところ

index.html

scaffoldで作成されたデフォルトのコード

対象ファイル:${rails_root}/app/views/notes/index.html.erb

<p id="notice"><%= notice %></p>

<h1>Listing Notes</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Content</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @notes.each do |note| %>
      <tr>
        <td><%= note.title %></td>
        <td><%= note.content %></td>
        <td><%= link_to 'Show', note %></td>
        <td><%= link_to 'Edit', edit_note_path(note) %></td>
        <td><%= link_to 'Destroy', note, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Note', new_note_path %>
index画面はこんな感じ

f:id:tocguitar1:20161215143954p:plain

まぁ、これはわかる。

このコードをリファクタリングしていく

まずindex.htmlの下記部分をパーシャルにする。

${rails_root}/app/views/notes/_note.html.erb

<tr>
  <td><%= note.title %></td>
  <td><%= note.content %></td>
  <td><%= link_to 'Show', note %></td>
  <td><%= link_to 'Edit', edit_note_path(note) %></td>
  <td><%= link_to 'Destroy', note, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>

そして、index.htmlを以下のように書き換える。

<p id="notice"><%= notice %></p>

<h1>Listing Notes</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Content</th>
      <th colspan="3"></th>
    </tr>
  </thead>
  <tbody>
    <% @notes.each do |note| %>
      <%= render 'note', note: note %>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Note', new_note_path %>

ぼくは正直この時点でだいぶつらい感じを覚えました。この部分ですね。

<% @notes.each do |note| %>
  <%= render 'note', note: note %>
<% end %>

これはnotes_controller.rbのindexアクションで定義されているインスタンス変数@notesNote.allで全てのNoteテーブルに関する情報をいれていて、それをeachで回しているというのが基本なのですが、先程パーシャル化した_note.html.erbrenderで呼出し、パーシャルで用いられている変数note:にeachで持ってきたnoteインスタンスを渡しているという処理になります。

さらにリファクタリングをする

このindex.html.erbをさらにこんな感じでリファクタリングすることができます。

<p id="notice"><%= notice %></p>

<h1>Listing Notes</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Content</th>
      <th colspan="3"></th>
    </tr>
  </thead>
  <tbody>
    <% @notes.each do |note| %>
      <%= render note %>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Note', new_note_path %>

はい!ツライですね!これは非常にツライ!

# 変更前
<% @notes.each do |note| %>
  <%= render 'note', note: note %>
<% end %>

# 変更後
<% @notes.each do |note| %>
  <%= render note %>
<% end %>

なんと以下のコードは

<%= render note %>

以下のコードを生成するのです!!

<%= render 'note', note: note %>

ああああ、ツライ!!!ツライよおおお!!

正直このあたりはなんでこういう動きをしているのか全くわかっておりません。今度調べて追記するかもしれないですが、どうでしょうか。

ここからさらにリファクタリングをする

なんと最終的にはこういうふうに記載ができます。

<p id="notice"><%= notice %></p>

<h1>Listing Notes</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Content</th>
      <th colspan="3"></th>
    </tr>
  </thead>
  <tbody>
    <%= render @notes %>
  </tbody>
</table>

<br>

<%= link_to 'New Note', new_note_path %>

あsdfjk;qうぇるいおp!!!

# 変更前
<% @notes.each do |note| %>
  <%= render note %>
<% end %>

# 変更後
<%= render @notes %>

もはやまったくわけがわからなくなってきましたが、要するにこういうことらしい。

以下のコードは

<%= render @notes %>

以下のコードを生成する!!!!

<% @notes.each do |note| %>
  <%= render note %>
<% end %>

おわりに

第一線で活躍するRailsプログラマーのみなさんにおかれましては本記事はカスのような内容すぎて逆に内を言いたいのかわからないかと思われますが、安心してください。

ぼくもよくわからなくってまいりました。

そもそもタイトルにある「インスタンス変数が生成するコード」というのも完全に間違っている可能性がありますが、第一線で活躍するRailsプログラマーのみなさんにおかれましてはマサカリを投げる事なく優しいご指導を頂けると嬉しいですのでそこのところよろしくお願いします!