Blokowe helpery w Ruby on Rails

08 lipca 2008, 10:28:11

Poziom: 0 | Kategoria: Komputerowo-internetowo, Ruby, Ruby on Rails, Techblog.

Bardzo przydatną rzeczą, którą możemy zrobić podczas refaktoryzacji kodu widoków jest dopisanie helperów akceptujących bloki kodu.

W Railsach standardowo mamy co najmniej kilka takich helperów, m.in. form_for, czy link_to (póki co w wersji EDGE). Nic nie stoi na przeszkodzie, aby dopisać swoje własne metody akceptujące bloki, które w widoczny sposób poprawiają czytelność kodu.

Jako przykład podam implementację rounded-box jako helper akceptujący blok. Końcowy efekt wyglądał będzie następująco:

<%- rounded_box do %>
Treść, która powinna znaleźć się w boksie
<% end -%>

Napisanie tego typu metod jest bardzo proste i opiera się na wykorzystaniu metody concat. Zakładam, że cały kod naszego boksu na postać (styl CSS zostawmy w spokoju):

<div class="rnd_container">
  <b class="rnd_top">
    <b class="rnd_b1"></b>
    <b class="rnd_b2"></b>
    <b class="rnd_b3"></b>
    <b class="rnd_b4"></b>
  </b>
<div class="rnd_content"> 
  <h2><p>Treść w boksie</p></h2>
</div>
  <b class="rnd_bottom">
    <b class="rnd_b4"></b>
    <b class="rnd_b3"></b>
    <b class="rnd_b2"></b>
    <b class="rnd_b1"></b>
  </b>
</div>

Powyższy kod można najprościej przetransportować do osobnego partiala i zapisac, np. w katalogu app/views/shared/_rounded_box.html.erb w lekko zmodyfikowanej wersji:

  <div class="rnd_container">
    <b class="rnd_top">
      <b class="rnd_b1"></b>
      <b class="rnd_b2"></b>
      <b class="rnd_b3"></b>
      <b class="rnd_b4"></b>
    </b>
  <div class="rnd_content"> 
    <h2><%= body %></h2>
  </div>
    <b class="rnd_bottom">
      <b class="rnd_b4"></b>
      <b class="rnd_b3"></b>
      <b class="rnd_b2"></b>
      <b class="rnd_b1"></b>
    </b>
  </div>

Sama metoda helpera wygląda następująco:

  def rounded_box(options={}, &block)
    options.merge!(:body => capture(&block))
    concat(render(:partial => "shared/rounded_box", :locals => options), block.binding)
  end

Jak widać oprócz bloku możemy przekazać do partiala swoje zmienne podając je jako parametry wywołania helpera. Cała magia polega na przechwyceniu zawartości bloku wywołaniem capture(&block) i skonkatenowaniem jej z naszym boksem.

Rozwiązanie szybkie, proste i jakże czytelne!

Tagi:

Komentarze do notki “Blokowe helpery w Ruby on Rails”:

  1. Radarek

    Trick z ‘concat’ jest bardzo przydatny.
    Ja także korzystam z prostszej wersji takich helperów, mianowicie:

    module ApplicationHelper def authenticated(&block) block.call if current_user end
    end

    widok:

    <% authenticated do %> Jakas tresc widoczna tylko dla zalogowanego. <%= render :partial => „login_info” %>
    <% end %>

  2. GhandaL

    Radarek: fajna rzecz, przyda się na pewno ;-)

  3. teamon

    Ja często robie coś w stylu:
    <% content „Header” do %>
    ...
    <% end %>

    czy <% sidebar … %>
    łatwo potem zmienić html takich boxów (w jednym miejscu)

  4. Seban

    http://www.pathf.com/blogs/2008/07/pretty-blocks-in-rails-views/ <- Tekst na ten sam temat po angielsku. Też warto przeczytać

Zostaw komentarz (Textile włączony):