Tworzenie Prostej Platformy Blogerskiej - Wyświtlanie Postów
Przez: Lukasz Muzyka, Z dnia:
Ten tutorial zakłada, że już ukończyłeś:
- Install Ruby on Rails
- Create Ruby on Rails application
- Create Static Pages - without this deploy will not work
- Install Git
- Create Remote Git Repository - optional but recommended
- Deploy application to Heroku
- Manage users with Devise
- How to add Twitter Bootstrap to Ruby on Rails application - Advised
- Creating Simple Blogging Platform - Creating Model
- Creating Simple Blogging Platform - Routes
Stworzyliśmy rutery, które pozwolą nam wpisać w przeglądarce adresy, które odpowiadają "akcjom" w naszym "kontrolerze". Ale czym są kontrolery i akcje? Prostymi słowy, kontroler to istota w naszym kodzie, która ma za zadanie zarządzać pewnym zasobem. W tym przypadku będą to posty. Kontroler to miejsce gdzie będziemy decydować się na interakcje pomiędzy naszą aplikacją i użytkownikami. Natomiast akcja jest "podzbiorem" kontrolera. Na przykład, będziemy mieć akcję, która tworzy post.
W naszym tutorialu zwrócimy uwagę na 7 standardowych akcji:
Nazwa Akcji | Rola |
---|---|
Show | Wyświetlanie pojedynczego rekordu |
Index | Wyświetlanie listy rekordów |
New | Wyświetlanie formularza nowego rekordu |
Create | Zapisywanie nowego rekordu do bazy danych |
Edit | Wyświetlanie formularza do edycji rekordu |
Update | Zapisywanie zmian z akcji "edit" |
Destroy | Usuwanie rekordu |
Krok 1: Stwórz kontroler
Podczas budowania dalej przyjrzymy się im uważnie pojedynczo, ale najpierw stwórzmy nowy, pusty kontroler dla postów.
bash
$ rails generate controller posts
create app/controllers/posts_controller.rb
invoke erb
create app/views/posts
invoke test_unit
create test/controllers/posts_controller_test.rb
invoke helper
create app/helpers/posts_helper.rb
invoke test_unit
create test/helpers/posts_helper_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/posts.js.coffee
invoke scss
create app/assets/stylesheets/posts.css.scss
Zauważ, że używamy liczby mnogiej ('posts'). Kiedy tworzyliśmy model używaliśmy liczby pojedynczej ('Post'). To jest jedna z konwencji Rails.
Szybka Rada: Jako nazw modeli zawsze używaj rzeczowników, które mają liczbę mnogą. W przeciwnym razie, kontrolery i modele będą miały problemy z poprawnym komunikowaniem się.
Krok 2: Wyświetl posty i zdefiniuj akcję
Dwie akcje odpowiadają za wyświetlanie rekordów: "Show" i "Index". Na początek zajmiemy się "index". Otwórz nowo stworzony posts_controller.rb
.
/app/controllers/posts_controller.rb
class PostsController < ApplicationController
end
Zaczniemy od zdefiniowania akcji index:
class PostsController < ApplicationController
def index
end
end
Zwyczajnie dodaliśmy pusty block
, który zaczyna się od deklaracji def index
i kończy z end
, prawie jak wszystko w Rails. Zawsze pamiętaj o zamykaniu bloków z end
. Jeżeli zapomnisz tego zrobić, wywołasz błąd, który będzie wyglądał jak ten:
Krok 3: Stwórz szablon HTML
Po tym, jak stworzyliśmy akcję w kontrolerze, by coś wyświetlić musimy abudować szablon HTML dla akcji. Zaczniemy od stworzenia prostego pliku wewnątrz folderu app/views/posts
i nazwiemy go index.html.erb
, dodamy mu jedną linijkę HTML:
/app/views/posts/index.html.erb
<h1>This will be a list of posts</h1>
Ponieważ nazwaliśmy szablon tak samo jak naszą akcję - "index". Rails dopasuje je do siebie, więc nie musimy niczego precyzować. Teraz możemy zrestartować naszą aplikajcę z rails server
i otworzyć adres URL, który wskazuje na indeks postów: http://localhost:3000/posts.
Wspaniale, wiemy, że apliakacja działa. Następną rzeczą, którą się zajmiemy będzie wyświtlanie wszystkich postów, które mamy w bazie danych. Musimy wykonać te dwa kroki:
- Pierwszy: musimy znaleźć posty w bazie danych - kontroler
- Drugi: wyświetlić listę na stronie - szablon HTML
Krok 4: Zmodyfikuj Kontroler
Otwórzmy kontroler i dodajmy trochę kodu:
/app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
@posts = Post.all
end
end
@posts
- to nazwa zmiennej, której użyjemy do przechowywania postów znalezionych w bazie dancyh. Na tę chwilę, wyciągniemy wszystkie znalezione posty. Oczywiście, będziemy musieli znaleźć lepszy sposób w przypadku, gdy w naszej bazie danych będzie dużo postów. Ale jak na razie, jesteśmy okej z tą prostą metodą.
Krok 5: Zmodyfikuj szblon HTML
Przez nadanie naszej zmiennej symbolu "@" zezwoliliśmy jesj na podróżowanie między kontrolerem a widokiem. Dlatego też, możemy jej użyć do wyświetlenia listy postów.
/app/views/posts/index.html.erb
<h1>This is a list of posts</h1>
<ul>
<% @posts.each do |p| %>
<li>
<h3><%= p.title %></h3>
<p><%= p.body %></p>
</li>
<% end %>
</ul>
Przejdź teraz na stronę http://localhost:3000/posts.
Krok 6: Użyj Bootstrap
W tym momencie możemy dodać link do naszych postów w menu strony, tak więc nie będziemy musieli więcej ręcznie wpisywać adresu URL. Wykorzystamy do tego Bootstrap CSS. Do application.html.erb
dodaj poniższy kod:
/app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %> alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<%= value %>
</div>
<% end %>
<nav class="navbar navbar-default" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<%= link_to "Demo App", root_path, class: 'navbar-brand' %>
</div>
<div class="collapse navbar-collapse" id="navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><%= link_to 'Posts', posts_path %></li>
<% if current_user %>
<li><%= link_to 'Logout', destroy_user_session_path, method: :delete %></li>
<% else %>
<li><%= link_to 'Login', new_user_session_path %></li>
<% end %>
</ul>
</div>
</div>
</nav>
<div class="container">
<%= yield %>
</div>
</body>
</html>
Krok 7: Zdefiniuj Akcję w Kontrolerze
Kontunuujmy i dodajmy stronę oddaną wyświtlaniu indywidualnych postów. Będzie to strona, na której ostatecznie będziemy mogli dodać system komentarzy.
Na początek, tak jak przedtem, musimy zdefiniować akcję wewnątrz kontrolera:
/app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
@posts = Post.all
end
def show
end
end
Krok 8: Dopasuj Nazwy
Następnie musimy dodać szablon HTML wewnątrz folderu /app/views/posts
o nazwie takiej samej, co nazwa akcji.
/app/views/posts/show.html.erb
<h1>This will be a individual post page</h1>
Krok 9: Uruchom rake Routes
Pojawia się pytanie: Kiedy użytkownik wpisze adres posta, jak znajdujemy ten właściwy po adresie URL? Spójrzmy na rutery, które poprzednio stworzyliśmy:
bash
$ rake routes
posts GET /posts(.:format) posts#index POST /posts(.:format) posts#create new_post GET /posts/new(.:format) posts#new edit_post GET /posts/:id/edit(.:format) posts#edit post GET /posts/:id(.:format) posts#show PATCH /posts/:id(.:format) posts#update PUT /posts/:id(.:format) posts#update DELETE /posts/:id(.:format) posts#destroy
Tym razem przyjrzyjmy się temu uważniej.
Nazwa Rutera | Typ Rządania | URI | Kontroelr#Akcja | Wymaga :ID |
---|---|---|---|---|
posts | GET | /posts(.:format) | posts#index | nie |
POST | /posts(.:format) | posts#create | nie | |
new_post | GET | /posts/new(.:format) | posts#new | nie |
edit_post | GET | /posts/:id/edit(.:format) | posts#edit | TAK |
post | GET | /posts/:id(.:format) | posts#show | TAK |
PATCH | /posts/:id(.:format) | posts#update | TAK | |
PUT | /posts/:id(.:format) | posts#update | TAK | |
DELETE | /posts/:id(.:format) | posts#destroy | TAK |
Krok 10: Zrozum Kolumny
Pierwsza kolumna pokazuje ścieżkę, której możemy użyć w linku. Dodamy do tej nazy albo _path
, albo _url
by zbudować stronę indeksową:
<%= link_to "All Posts", posts_path %>
Zwyczajnie bierzemy przedrostek posts
, dodajemy _path
i rails już wie, że chcemy stworzyć link do kontrolera posts
i akcji index
.
Druga kolumna przedstawia metodę przy pomocy której dokonujemy transferu informacji pomiędzy serwerem i przeglądarką. Zasadniczo GET znaczy, że przegladarka "daje" dane z serwera i nic więcej nie robi (PUT, POST, PATCH, DELETE). Na przykład "edit" dostaje post z serwera. Ten formularz będzie wypełniony istniejącymi już tytułem i treścią posta. Kiedy klikniemy "Save" będzie on wysłany do serwera do akcji "update" przy użyciu metody PUT.
Trzecia kolumna to URI (Uniform Resource Identifier). Jest to mniej więcej to, co zobaczymy w pasku adresu przeglądarki. Ważną rzeczą do odnotowania tutaj są wszystki symbole z ":". Te parametry są wymagane przez nasz ruter żeby mógł on skierować nas do właściwego posta. Weźmy edit_post
dla przykładu. Tutaj URI to /posts/:id/edit(.:format)
. :id
jest identyfiaktorem samego posta. Uzyjemy go by znaleźć post w bazie danych. Na przykład, jeżeli chcemy edytować post z numerem ID 124, URI będzie wyglądał tak: http://localhost:3000/posts/124/edit
.
Dodałem jedną kolumnę żebyście jasno widzielu, które akcje wymagają podania parametrów.
Czwarta kolumna wskazuje kontroler i akcję, z którymi ruter oddziałowuje.
Krok 11: Użyj Parametru i szablonu edycji HTML
Z całą tą wiedzą możemy wrócić do kontrolera i znaleźć pojedyncze posty przy użyciu parametrów z URI.
/app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
@posts = Post.all
end
def show
@post = Post.find(params[:id])
end
end
Tym razem stworzyliśmy zmienną @post
, w której zapiszemy rezultat wyszukiwania posta wśród wszystikch postów po jego parametrze :id
. Ten id znajduje się w URI. Możemy teraz uzyć tej zmiennej do wyświetlenia posta na jego stronie.
/app/views/posts/show.html.erb
<h1><%= @post.title %></h1>
<p><%= @post.body %></p>
Na konieć przejdź do pliku index.html.erb
, musimy tylko zmienić tytuł posta na link do jego strony.
/app/views/posts/index.html.erb
<h1>This is a list of posts</h1>
<ul>
<% @posts.each do |p| %>
<li>
<h3><%= link_to p.title, post_path(p.id) %></h3>
<p><%= p.body %></p>
</li>
<% end %>
</ul>
Powyżej możesz zobaczyć jak dodaliśmy _path
do przedrostka post
i jak użylismy p.id
jako parametru dla linka.
Dodaj komentarz
Możesz się zalogować by skomentować