Przekazywanie do layout

Witam!

Chcial bym zrobic menu na stronie, w ktorym bedzie rozwijane pole galeria i rozwijac sie tam beda odpowiednio galerie dodane przez uzytkownika. Beda one przechowywane w bazie danych i jesli uzytkownik doda jakas galerie, to zwiekszy sie ich ilosc w menu. Niestety jest problem, bo jak przystalo, menu jest tworzone tylko raz w layout->application a do tego nie ma kontrolera (jest kontroler application, ale nie udalo mi sie za jego pomoca tego zrobic). Przechodzac do setna sprawy, to w kontrolerze musze cos wyciagac z bazy danych i udostepniac dla widoku. Jak to zrobic w przypadku widoku layoyt->application?

Dzieki za pomoc!

Pozdrawiam

yield :costam
content_for :costam
http://apidock.com/rails/ActionView/Helpers/CaptureHelper/content_for

ale yeld jest do tego, zeby w tym miejscy umieszczac strony a nie, zeby w layout mozna bylo uzywac czegos z bazy danych…

może zdefiniuj jakiegoś helpera w application_helper?

ale czy moge w helperze zrobic

@galeria = Gallery.find(:all)

a potem w layout->application:

[code]<% @galeria.each do |galeria| %>

                  <dd><%= link_to "Galeria", "/galeria/#{galeria.name}" %></dd>

<% end %>[/code]
?

[quote=rysic]ale czy moge w helperze zrobic

@galeria = Gallery.find(:all)

a potem w layout->application:

[code]<% @galeria.each do |galeria| %>

                  <dd><%= link_to "Galeria", "/galeria/#{galeria.name}" %></dd>

<% end %>[/code]
?[/quote]
tak, robisz coś takiego w application_helper:

def show_galeries res = "" Gallery.find(:all).each do |galeria| %> res << "<dd>#{link_to "Galeria", "/galeria/#{galeria.name}"}</dd>" end res end
OK, to nie jest najbardziej elegancji kod, ale ilustruje problematykę :slight_smile:

Działa :smiley: Wielkie dzieki! :slight_smile:

Ale wiecie że operacje na modelach w warstwie widoku (helpery, layouty) to bardzo, bardzo zła praktyka rodem z PHP (a i to tego co bardziej amatorskiego, bo zawodowcy używają Smarty)?

Moim skromnym zdaniem za proponowanie takich rozwiązań na tym forum powinno się dostawać ostrzeżenia i dalej bany :wink:

Tak naprawdę chodzi wam o coś, co w Railsach <2.0 było dostępne jako komponenty, a teraz można zrobić za pomocą Rails Cells:
http://cells.rubyforge.org/

Teoretycznie masz rację. Ale tylko w teorii, bo:

  1. cells nie mają żadnej dokumentacji. Nie wzbudza to mojego zaufania do projektu
  2. cells nie są częścią frameworka. Czy mam gwarancję, że będzie dalej rozwijany?
  3. wzorce projektowe to nie dogmaty. Lepiej raz użyć w helperze operacji na modelu (oczywiście odczytu, nie zmiany), niż instalować masę obcego kodu. Wszystko jest kwestią skali.

[quote=tomek1024]Teoretycznie masz rację. Ale tylko w teorii, bo:

  1. cells nie mają żadnej dokumentacji. Nie wzbudza to mojego zaufania do projektu[/quote]
    A sprawdziłeś chociaż?
    cells site -> http://cells.rubyforge.org/documentation.html -> http://cells.rubyforge.org/rdoc/index.html

Właściwie to nie powinienem ciągnąć dyskusji po czymś takim, ale mam dziś dobry dzień :wink:

Taką samą gwarancję jak to, że sam framework będzie rozwijany. Czyli żadną.

Lepiej postąpić w zgodzie ze wzorcami, a dopiero potem - będąc w pełni świadomym co się robi, dlaczego łamie MVC i czym to grozi - ewentualnie je łamać, jeśli nie ma innego wyjścia. Łamanie wzorców przed ich poznaniem i zrozumieniem to najlepszy sposób na postrzelenie się w stopę, a potem, po długiej i bolesnej rekonwalescencji [refaktoring], ponowne odkrycie ameryki [wzorców]. Oczywiście tak też można. Co nie znaczy że należy do tego zachęcać.

Jasne że to nie dogmaty, można w ogóle wzorce wyrzucić do kosza. Jest nawet cały język przyciągający rzesze myślących w ten sposób. :wink:

Taka jest teoria. W praktyce w tym wypadku musiałbyś w kontrolerze pobrać wszystkie galerie i przekazać do widoku. Jaki z tego zysk? Żaden. MVC webowe to nie jest stricte MVC, które było zaprojektowane do aplikacji GUI. Jeśli w widoku nie chcesz zrobić Gallery.find(:all) (bo rozumiem, że o to Ci chodzi) to można dołożyć małą abstrakcję w postaci Gallery.all_for_display (czy coś takiego). Jak zmieni się logika co to jest ‘all for display’ to wystarczy zmienić tą metodę i tyle. Wracają do kwestii view vs model to w praktyce pisanie widoków, które nie mają wiedzy o modelu nie istnieje. Zwykłe odwołanie user.name w widoku jest przecież złamaniem tej zasady (widok wie że user ma atrybut ‘name’!). Nie mówiąc już o user.galleries.active.each do {|g| }. Tylko, że spróbuj pisać kod, który nie będzie łamać tych zasad. Gwarantuję, że sobie dasz spokój.

Radarek, ale po to właśnie są komponenty :slight_smile:

A że widok zakłada pewną strukturę otrzymanych danych… normalne :wink:

[quote=Tomash]Radarek, ale po to właśnie są komponenty :slight_smile:

A że widok zakłada pewną strukturę otrzymanych danych… normalne ;)[/quote]
Każda taka abstrakcja wprowadza pewien narzut złożoności. Nie zawsze potrzebujesz tego. Nie wiem czy oglądałeś, ale bardzo dobrze opowiadał o tym Jamis Buck na RubyConf2008 (http://rubyconf2008.confreaks.com/recovering-from-enterprise.html). Komponenty, wzorce, fabryki klas… a czasem potrzebujesz po prostu 1-2 metod ;-).

Nie oglądałem, ale dziękować za linka - obiecuję nadrobić zaległości :slight_smile:

Chyba już wolę taki kod mieć w widoku, w stylu
Category.find(:all).each do |c|

  • <%= c.name %>
  • Niż ładować go do helperów, do których z definicji zagląda się rzadziej w poszukiwaniu fakapów.

    [quote=Tomash]Chyba już wolę taki kod mieć w widoku, w stylu
    Category.find(:all).each do |c|

  • <%= c.name %>
  • Niż ładować go do helperów, do których z definicji zagląda się rzadziej w poszukiwaniu fakapów.[/quote]
    Jak najbardziej się zgadzam.

    [quote=Tomash][quote=tomek1024]Teoretycznie masz rację. Ale tylko w teorii, bo:

    1. cells nie mają żadnej dokumentacji. Nie wzbudza to mojego zaufania do projektu[/quote]
      A sprawdziłeś chociaż?
      cells site -> http://cells.rubyforge.org/documentation.html -> http://cells.rubyforge.org/rdoc/index.html

    Właściwie to nie powinienem ciągnąć dyskusji po czymś takim, ale mam dziś dobry dzień ;)[/quote]
    Tutoriala nie ma. Sugerują kanał IRC :slight_smile: A na link RDoc nie kliknąłem, moja wina.

    Taką samą gwarancję jak to, że sam framework będzie rozwijany. Czyli żadną.[/quote]
    Tak samo nie mamy pewności, czy ruby będzie rozwijany :slight_smile: Jednak chyba jasne jest, że prawdopodobieństwo, że cells nie będzie rozwijane, jest większe, niż to, że umrze ror. Nie chcę oceniać dojrzałości tego projektu, bo go nie znam. Ale włączanie go do projektu to dodawanie kolejnej zależności od cudzego kodu - ma to z pewnością sens, jeśli poprawi ilość i czytelność kodu, na pewno nie robiłbym tego dla efektu, który mogę uzyskać trzema helperami.

    Lepiej postąpić w zgodzie ze wzorcami, a dopiero potem - będąc w pełni świadomym co się robi, dlaczego łamie MVC i czym to grozi - ewentualnie je łamać, jeśli nie ma innego wyjścia. Łamanie wzorców przed ich poznaniem i zrozumieniem to najlepszy sposób na postrzelenie się w stopę, a potem, po długiej i bolesnej rekonwalescencji [refaktoring], ponowne odkrycie ameryki [wzorców]. Oczywiście tak też można. Co nie znaczy że należy do tego zachęcać.[/quote]
    Jasne, ale weź też pod uwagę krzywą uczenia się. rysic mial prosty problem, i nie mógł skończyć swojej aplikacji. Ja mu podsunąłem proste, ale nie do końca eleganckie rozwiązanie. Bardzo fajnie, że podsunałeś mu lepszy sposób, trzeba mieć nadzieję, że będzie pamiętać, że można to zrobić lepiej, ale oczekiwanie, że ktoś, kto dopiero uczy się railsów będzie chciał się wgrażać w cellsy, uważam za nierealistyczne.

    A czy wrzucić cały kod do templatki, czy do helpera - to już wyłącznie kwestia gustu.