Kurs Ruby on Rails

Kurs Ruby on Rails – Lekcja 4 – Kontrolery aplikacji

Czego się nauczycie?

  • Jak stworzyć kontroler
  • Tworzenie akcji i metod wewnątrz kontrolera
  • Jakie są metody protokołu HTTP
  • Podstawy routingu
  • Przekazywanie parametrów
  • Jak stworzyć podstawowy widok i przekazać do niego dane

Niezbędnik kursu:

1. Tworzymy nowy kontroler

$ rails g controller home index

Powyższa komenda wygeneruje:

  • kontroler HomeController z akcją index
  • doda odpowiedni wpis do pliku config/routes.rb
  • stworzy odpowiedni widok dla akcji index, plik CSS oraz plik home_helper.rb
  • plik testów kontrolera
  create  app/controllers/home_controller.rb
    route  get 'home/index'
  invoke  erb
  create    app/views/home
  create    app/views/home/index.html.erb
  invoke  helper
  create    app/helpers/home_helper.rb
  invoke  assets
  invoke    scss
  create      app/assets/stylesheets/home.scss
  invoke  test_unit
  create    test/controllers/home_controller_test.rb

Utworzony kontroler powinien się prezentować w następujący sposób

  class HomeController < ApplicationController
    def index
    end
  end

CRUD

Zanim wyjaśnimy dlaczego nazwaliśmy naszą metodę index, musimy dowiedzieć się co to jest CRUD. CRUD (od ang. Create, Read, Update, Delete) są to cztery rodzaje funkcji, które występują w aplikacjach korzystających z baz danych.

I w tej konwencji tworzymy nazwy naszych akcji w kontrolerach.

Dla funkcji Create stworzymy akcje create, która będzie odpowiadała za tworzenie obiektów

  def create
  end

Dla funkcji Read stworzymy akcje new, edit, show i index, które to będą odpowiadały za wysyłanie danych do użytkownika. I tak odpowiednio:

  • new – wysyła dane potrzebne do utworzenia nowego obiektu
  • edit – wysyła dane potrzebne do edycji istniejącego obiektu
  • show – wysyła dane potrzebne do wyświetlenia obiektu
  • index – wysyła dane potrzebne do wyświetlenia listy obiektów
  def new
  end

  def edit
  end

  def show
  end

  def index
  end

Dla funkcji Update stworzymy akcje update, która będzie odpowiadała za edycję obiektów

  def update
  end

Dla funkcji Delete stworzymy akcje destroy, która będzie odpowiadała za usuwanie obiektów

  def destroy
  end

Nazewnictwo kontrolerów

Stworzony przez nas HomeController, nie odwołuje się do żadnego stworzonego przez nas modelu. Jak już wiemy, kontroler pośredniczy pomiędzy widokiem, a modelem.

W wypadku, gdy chcemy stworzyć kontroler obsługujący zapytania i żądania dla któregoś z naszych modeli, to musimy użyć liczby mnogiej nazwy modelu. Jeżeli weźmiemy jako przykład model Post, to dla niego tworzymy kontroler o nazwie PostsController.

Gdy chcemy wykorzystać generator, to również musimy podać liczbę mnogą.

  $ rails g controller posts index

2. Routing

Zanim wyświetlimy nasze dane, to musimy dowiedzieć się co nieco o routingu.

Protokół HTTP

Protokół HTTP odpowiada za wymianę informacji pomiędzy programami. W naszym przypadku tymi programami jest nasz serwer Rails oraz przeglądarka. Posiada on metody, które odpowiadają funkcją CRUD, a mianowicie:

  • GET – odpowiada za pobieranie danych (Read)
  • POST – odpowiada za przyjmowanie danych (Create)
  • PUT – odpowiada za przyjmowanie danych do aktualizacji (Update)
  • PATCH – odpowiada za aktualizację części danych (Update)
  • DELETE – odpowiada za usuwanie zasobów (Delete)

Konfiguracja routingu

Abyśmy mogli wysyłać zapytania z naszej przeglądarki za pomocą linków na nasz serwer, musimy odpowiednio skonfigurować plik config/routes.rb

Aktualnie, powinien on wyglądać następująco

  Rails.application.routes.draw do
    get 'home/index'
  end

Co wytłumaczymy jako zapytanie metodą GET, kierującą nas do kontrolera home, ku akcji index. W routes.rb możemy w taki sposób skonfigurować routing. Możemy również wykorzystać funkcję resources.

  Rails.application.routes.draw do
    resources :home
  end

Co skonfiguruje nam cały routing potrzebny pod CRUD.

By podejrzeć aktualne ścieżki, użyjmy w konsoli polecenia

$ rake routes

Co aktualnie wyświetli nam

  home_index GET        /home(.:format)                                                                          home#index
             POST       /home(.:format)                                                                          home#create
    new_home GET        /home/new(.:format)                                                                      home#new
   edit_home GET        /home/:id/edit(.:format)                                                                 home#edit
        home GET        /home/:id(.:format)                                                                      home#show
             PATCH      /home/:id(.:format)                                                                      home#update
             PUT        /home/:id(.:format)                                                                      home#update
             DELETE     /home/:id(.:format)                                                                      home#destroy

Przekazywanie parametrów

Symbol :id oznacza, że do ścieżki jaką podamy w przeglądarce musimy dodać id obiektu dla którego chcemy tą akcje wykonać, np.

  localhost:3000/home/1

Co pokieruje nas do kontrolera home, do akcji show z parametrem id równym 1. Aby uzyskać dostęp do tego parametru musimy skorzystać z metody params i przekazać jej klucz parametru, który chcemy uzyskać

  def show
    @id = params[:id]
  end

Dodatkowe parametry

Dodatkowy parametr przekażemy poprzez dodanie znaku ? do naszej ścieżki

  localhost:3000/home/1?extra_param=hello

Teraz przy wywołaniu tego parametru, zostanie nam zwrócone hello

  puts params[:extra_param]
  "hello"

By przekazać więcej parametrów, po każdym kolejnym należy dodać znak &

  localhost:3000/home/1?extra_param=hello&another_param=bye

Przekazywanie tablicy w parametrach

Aby przekazać tablice w parametrach należy utworzyć parametr tablicy np. arr[] i do niego kolejno przekazywać wartości tak jak w przypadku wielu parametrów.

  localhost:3000/home/1?arr[]=1&arr[]=2&arr[]=3

Co przy wywołaniu tego parametru zwróci nam tablicę

  puts params[:arr]
  [1, 2, 3]

Organiczenie resources oraz root aplikacji

Jako, że aktualnie potrzebujemy wyłącznie akcji index, to możemy to przekazać do metody resources kluczem only.

  Rails.application.routes.draw do
    resources :home, only: [:index]
  end

Aby sprawdzić czy wszystko działa należy uruchomić nasz serwer

  $ rails s

I zobaczmy nasz widok wpisując w przeglądarkę

  localhost:3000/home

Powinniśmy teraz zobaczyć nasz wygenerowany widok. Możemy również skonfigurować home#index jako domyślną ścieżkę naszej aplikacji, korzystając z funkcji root.

  Rails.application.routes.draw do
    root 'home#index'
  end

Teraz, aby wyświetlić nasz widok, wystarczy wejść na

  localhost:3000

3. Przekazywanie danych do widoku

Aby przekazać dane z kontrolera do widoku, trzeba mu powiedzieć, w jaki on sposób ma to zrobić.

  class HomeController < ApplicationController
    def index
      render('home/index', locals: { message: 'Cześć' })
    end
  end

Powyższa metoda kieruje nas do widoku index, znajdującego się w folderze home oraz przekazujemy mu zmienną message, jako zmienną lokalną widoku.

By wyświetlić ją w naszym widoku, wystarczy dodać pliku /home/index.html.erb

  <%= message %>

Tak naprawdę nie musimy przekazywać tego, na który widok chcemy się kierować. Jeżeli tego nie przekażemy, to railsy automatycznie będą szukać w folderze z nazwą kontrolera (w tym wypadku home) pliku o nazwie akcji (index).

  class HomeController < ApplicationController
    def index
      render(locals: { message: 'Cześć' })
    end
  end

Jest jeszcze jeden sposób przekazywania zmiennych do widoku, a mianowicie za pomocą zmiennych instancji (zmienne poprzedzone znakiem @).

  class HomeController < ApplicationController
    def index
      @message = 'Cześć'
    end
  end

Musimy jeszcze tylko pamiętać, by zmienić zmienną w widoku.

  <%= @message %>

Po zapisaniu plików i odświeżeniu strony powinniśmy zobaczyć naszą wiadomość z kontrolera w naszej przeglądarce.

Więcej o widokach dowiecie się w kolejnej lekcji.

4. Praca własna

Rozwiązanie pracy własnej z lekcji 3
https://github.com/binarapps/ruby-on-rails-course/pull/2/files

Przed zabraniem się za pracę domową, możecie przygotować sobie restowy plugin do przeglądarki (lub korzystać z postmana lub curla), aby bezpośrednio uderzać na nowe kontrolery. Pamiętajcie, że wpisując link do przeglądarki, będziemy tylko wysyłać zapytania metodą GET.

1. Stworzyć kontrolery Users, Posts oraz Comments

2. Zdefiniować we wszystkich kontrolerach metody new, create, edit, update, show, index, destroy

3. Zdefiniować routing dla tych kontrolerów i ich metod

4. Przygotować pliki z widokami dla odpowiednich metod (analogicznie do home/index.html.erb)

5. W widoku index kontrolera Posts przekazać własną zmienną do widoku

6. Ustawić root na akcję index z kontrolera Posts

7. (trudne) W każdej akcji przygotować odpowiednie query np.

  def index
    @posts = Post.all
  end

8. (trudne) Do akcji show w kontrolerze Posts przekazać parametr, który wyświetlimy w widoku.

Przydatne linki

http://guides.rubyonrails.org/ 
http://api.rubyonrails.org/ 
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods 
https://guides.rubyonrails.org/action_controller_overview.html 
https://guides.rubyonrails.org/routing.html

Przeczytaj również o...

Dołącz do naszego zespołu!

Zobacz oferty pracy