Przenoszę dyskusję tutaj z offtopic w wątku “Staż/praktytka Ruby on Rails”
Plik README opisuje tylko mały fragmencik pomysłu, dość by można zacząć pracę.
Nie lubię proceduralnego podejścia helperów. Jeden płaski namespace powoduje, że albo helper staje się bardziej skompliowany niż trzeba albo muszę tworzyć wiele helperów o coraz bardziej skomplikowanych nazwach:
[code=ruby]description(user)
description(profile) # description musi rozróżnić z jakim modelem ma do czynienia, słaba czytelność kodu
alternatywa
user_description(user)
profile_description(profile) #redundancja przy użyciu[/code]
Ja chcę czegoś takiego:
user.description
profile.description
Co ważne: user i profile w tym wypadku to nie modele ActiveRecord ale ich reprezentacje.
Sevos słusznie zwrócił uwagę, że pisanie:
- user = r(@user)
nie wygląda najlepiej. Dlatego kolejnym krokiem będzie rozszerzenie resource_controller tak, by automatycznie opakowywało objekty ActiveRecord w odpowiednie reprezentacje i tylko reprezentacje przekazywało do widoku. Dodatkowym bonusem takiego rozwiązania może być niejako przy okazji wyłączenie destrukcyjnych metod z ActiveRecord tak, by nie dało się we view zrobić user.delete.
Moim zdaniem z każdym rodzajem danych (model ActiveRecord, jego pole typu String, Time czy Bool) należy powiązać metody prezentacyjne. String domyślnie powinien się escapować - ale też mieć reprezentację w postaci input. Natomiast nie uważam, żeby dobrym pomysłem było dodawanie takich metod do klas bazowych. Stąd pomysł:
Opakowujemy ActiveRecord (np. user) w ActiveRecordRepresentation (user_representation), prosty obiekt proxy. Gdy wywołamy na nim dowolną metodę jest ona przekazywana do objektu oryginalnego. To co zwrócił user jest następnie opakowywane w kolejną reprezentację, zależną od typu zwracanej danej.
Gdy wywołamy user_representation.login to otrzymamy objekt StringRepresentation. StringRepresentation oferuje metody: to_s (która zwraca oryginalny login potraktowany html_escape), text_field (tworzy input z odpowiednim name) i pozostałe. W ten sposób w widoku wybieramy jak chcemy przedstawić dane pole:
Kod: ruby
user.login # => ERB/Haml uruchamia to_s, otrzymujemy login potraktowany html_escape
user.login.text_field # => tworzy pole input typu text
user.login.label # => tworzy label z odpowiednim id oraz domyślnym tekstem 'Login'
user.login.label("Nazwa użytkownika", :class => 'login') # => tworzy label z własnym tekstem i klasą CSS
Do tego w katalogu /app/representations można dodawać lub nadpisywać domyślne metody, np. DateRepresentation.to_s może wyświetlać aktualny czas w formacie wygodnym dla docelowych użytkowników (np. mm/dd/yy lub dd/mm/yy).
Nie chcę mieć kolejnego sprytnego/semantycznego form buildera, takie rozwiązania już istnieją. Chcę móc wywoływać metody w sposób naturalny dla każdego innego obszaru Ruby, czyli pisać user.form zamiast form_for(user). Nie interesuje mnie też na razie super szybkość i zużycie pamięci a jedynie wygoda korzystania.