Strona powitalna / strona główna w Ruby on Rails - najlepsze praktyki

80

Moja strona główna (lub strona powitalna) będzie składać się z danych z dwóch modeli (nazwijmy je autorami i postami). Jestem nowy w railach i nie jestem pewien, jaki jest najlepszy sposób, aby to osiągnąć.

Czy powinienem utworzyć nowy kontroler o nazwie welcome, który zbiera dane od autorów i postów, a następnie wyświetla je w widoku indeksu powitalnego? A może powinienem mieć mile widziany widok pod model postu, który również pobiera dane od autorów? Lub w inny sposób, aby to osiągnąć?

Rozumiem, jak to wszystko technicznie zrobić, ale nie jestem pewien, jaka jest najlepsza metoda korzystania z ramy szyn.

Espen
źródło

Odpowiedzi:

52

Pytanie brzmi, czy Twoja strona główna to tylko strona docelowa, czy będzie to grupa stron? Jeśli jest to tylko strona docelowa, nie spodziewasz się, że użytkownicy będą się tam długo kręcić, chyba że będą gdzie indziej. Jeśli jest to grupa stron lub podobna do istniejącej grupy, możesz dodać akcję do kontrolera, która jest najbardziej podobna.

To, co zrobiłem dla mojego obecnego projektu, to nazwanie kontrolera Static, ponieważ potrzebuję 3 statycznych stron. Strona główna jest jedną z nich, ponieważ nie ma nic do zobaczenia ani zrobienia poza przejściem gdzie indziej.

Aby wyznaczyć trasę domyślną, użyj następujących poleceń w routes.rb:

# Place at the end of the routing!
map.root :controller => 'MyController', :action => :index

W moim przypadku byłoby to:

map.root :controller => 'static', :action => :index

Jeśli chcesz, możesz utworzyć kontroler tylko dla tej strony głównej. Nazwałbym to głównym lub czymś, co pamiętasz, a co odnosi się do strony głównej. Stamtąd możesz pobrać dane i modele i przejść do widoku wyjściowego.

class MainController < ApplicationController
  def index
    @posts = Posts.find(:all, :limit => 10, :order => 'date_posted', :include => :user)
  end
end

Zakładając, że masz poprawnie zdefiniowane relacje w modelu, szablon do dopasowania będzie bardzo prosty.

Powodzenia, mam nadzieję, że to pomoże.

Robert K.
źródło
Czyli pisanie @posts = Posts.find( ...lub @posts = Posts.allcoś podobnego w tym nowym kontrolerze / akcji nie byłoby uważane za naruszenie zasad DRY, mimo że taki kod może już pojawić się w akcji Postkontrolera index? Czy istnieje lepszy (bardziej modułowy) sposób, który wykorzystuje napisany już kod akcji Postkontrolera index?
LazerSharks
127

Wydaje się, że nie ma jednej najlepszej praktyki.

(1) Standardowy config/routes.rbplik wydaje się sugerować, że strona główna (lub strona główna / powitalna) powinna być obsługiwana przezwelcome#index . Jeśli miałbyś się tym kierować, to do wygenerowania odpowiedniego welcome#indexkontrolera / akcji możesz użyć następującego polecenia:

rails generate controller Welcome index

Następnie w programie config/routes.rbmożesz usunąć trasę GET (get "welcome/index" ) dodaną automatycznie przez generator i umieścić trasę root root 'welcome#index'(lub root :to => 'welcome#index'w Railsach < 4) na początku pliku, ponieważ prawdopodobnie będzie to Twoja najpopularniejsza trasa i powinna zostać dopasowana jako pierwsza.

Pamiętaj też, aby usunąć public/index.html w Railsach < 4.

(2) oficjalny Ruby on Rails Routing prowadzących zastosowań PagesController. Właściwie to sugeruje pages#main, chociaż wydaje mi się, że bardziej sensowne jest wybranie go pages#home(ponieważ „strona główna” jest wszechobecnym terminem / pojęciem). Dodatkowo, kontroler może obsługiwać inne strony zorientowane działania, takie jak pages#about, pages#contact, pages#terms, pages#privacy, itd

(3) Ruby on Rails Tutorial , idzie z static_pages#homei static_pages#helpitp, choć nie podoba mi się pomysł oznaczając ten kontroler z „statyczne”. Te strony prawdopodobnie nadal będą miały pewne dynamiczne aspekty, szczególnie strona główna!

(4) Chociaż nie omawia, jak obsługiwać stronę główną , RailsCast # 117 na stronach semi-statycznych sugeruje jeszcze jeden zestaw podejść do zasobów tylko do wyświetlania .

Preferuję 1 i / lub 2. W scenariuszu „i” możesz użyć powitalnego # indeksu i stron # informacji itp., Podczas gdy w scenariuszu „lub” możesz użyć strony # strona główna, strony # informacje, itd. Gdybym był zmuszony do wyboru, wybrałbym opcję 2 tylko dlatego, że otrzymujesz mniej kodu. A tak przy okazji, 2 i 3 są prawie takie same, poza słowem „statyczne”.

user664833
źródło
12
Dobra odpowiedź, wybiorę 2) strony # home.
Neeraj
3
IMHO, ta odpowiedź autorstwa @ user664833 powinna być zaakceptowaną odpowiedzią. Wyrażanie jasno zbadanej i przemyślanej logiki.
Betjamin Richards
29

Zadałem sobie coś takiego, kiedy po raz pierwszy uruchomiłem Rails. Oto, co musisz wiedzieć:

  • Modele niekoniecznie są bezpośrednio powiązane z kontrolerami i widokami.

Oznacza to, że określona kombinacja kontrolera / widoku może działać z tyloma modelami, ile potrzeba do wygenerowania tej konkretnej strony.

Celem kontrolera jest przygotowanie zbioru danych, który chcesz wyświetlić, niezależnie od tego, jakie modele są używane do przechowywania tych danych.

Celem widoku jest następnie wyświetlenie tych danych w najbardziej odpowiedni sposób.

Innymi słowy, kombinacje kontrolera / widoku nigdy nie są „pod” określonym modelem. Używają modeli, ale nie są pod nimi w żadnej hierarchicznej relacji. W rzeczywistości są rówieśnikami modelami, których używają.

Myślę, że zamieszanie pochodzi z przykładu generatora rusztowań znalezionego w AWDR i innych tekstach wprowadzających, takich jak:

skrypt ruby ​​/ kontroler generowania modelu szkieletu

Wiem, że ta domniemana relacja między modelem a kontrolerem / poglądami trochę mnie zdezorientowała. Ale tak naprawdę nie ma ścisłego związku. Gdyby tak było, byłoby bardzo trudno zrobić cokolwiek skomplikowanego z podejściem MVC. I oczywiście tak nie jest.

Mam nadzieję że to pomoże.

-- Jan

Jan
źródło
10
Jaka jest twoja odpowiedź na to pytanie?
Mark Wilden
Zamiast konkurować z innymi odpowiedziami (które są bardziej bezpośrednio związane z przedstawionym problemem, jaki ma pytający), jest to związane z błędnym przekonaniem, które John postrzega jako osobę pytającą . To jest przydatne. Nie ma powodu, by Jan powtarzał to, co powiedzieli inni, aby zająć się aspektem pytania, do którego nie odnieśli się.
ikonoklast
11

Najlepszą praktyką byłaby Twoja pierwsza sugestia. Utwórz kontroler powitalny i dzwoń do rekordów z dowolnych modeli. Miej główny punkt trasy do tego kontrolera. Bardzo czysty i odpowiedni.

allesklar
źródło
9

Zwróć uwagę, że w Rails3 poprawnym sposobem na rozwiązanie tego problemu jest dodanie następującego wiersza na końcu pliku tours.rb:

root :to => "welcome#index"

i usuń plik public / index.html.erb.

Należy również pamiętać, że indeks powitalny # odpowiada czynności indeksowania w kontrolerze WelcomeController, a kod z odpowiedzi Wicked Flea wyglądałby następująco:

class WelcomeController < ApplicationController
  def index
    @posts = Posts.find(:all, :limit => 10, :order => 'date_posted', :include => :user)
  end
end
irakli
źródło
1
Czy nie powinien to być kontroler „wita” lub pojedynczy zasób, użyj akcji show.
dangerousdave
9

Ta odpowiedź jest jak w Railsach 3.2.1.

Najpierw skonfiguruj kontroler dla stron, nazwany na przykład static:

$ rails generate controller static

W pliku app/controllers/static_controller.rb:

class StaticController < ApplicationController
    def index       
    end
end

Utwórz nowy plik widoku app/views/index.html.erb

Na koniec skonfiguruj config/routes.rb:

MyApp::Application.routes.draw do
   match 'home', :to => "static#index"
   root :to => "static#index"
end

Spowoduje to utworzenie obu /homei /przejście do tego, co umieścisz w właśnie utworzonym pliku widoku.

Naoise Golden
źródło
Bardzo fajne rozwiązanie! Jestem szalony, ale sugerowałbym, aby druga linijka była czytanamatch 'home' => 'static#index'
Anconia
6

Utwórz nowy kontroler nazwany tak odpowiednio, jak możesz. PodsumowanieController? StartController? DailyFrontPageController? Będziesz miał pomysł.

Co więcej, poważnie bym się zastanowił nad stworzeniem nowego modelu, nie opartego na ActiveRecord, który zbiera informacje z modeli autora i postów (lub cokolwiek są ich prawdziwe nazwy) do prezentacji w Twoim widoku. Alternatywą jest zebranie danych w kontrolerze, co prawie na pewno będzie bałagan - za każdym razem, gdy tego próbowałem, i próbowałem dużo. Oddzielny model wydaje się być znacznie bardziej uporządkowany.

Jeśli przetwarzanie jest stosunkowo proste, dlaczego nie spróbować najpierw zbudować danych w kontrolerze, a następnie zawinąć dane wyjściowe w Struct, a następnie zastąpić Struct prawdziwą klasą i przenieść tam konstrukcję, refaktoryzując do końca. Nie powinno to zbytnio zwiększać całkowitego czasu (większość kodu można ponownie wykorzystać), a uzyskasz dobry pomysł, co działa najlepiej dla Ciebie.

Mike Woodhouse
źródło