How does UX transform businesses? The effects of usability testing
It has already become clear that User Experience (UX) is a key factor in shaping how companies build a business. The customer-centric approach has almost completely replaced […]
Kurs Ruby on Rails – Lekcja 5 – Formularze aplikacji
Po ostatniej lekcji powinniśmy mieć już utworzone wszystkie potrzebne nam pliki z widokami. Teraz musimy je uzupełnić czymś ciekawym, ale zanim to zrobimy wytłumaczymy sobie ich rozszerzenia. Jak możemy zauważyć nasze pliki z widokami posiadają rozszerzenie .html.erb
. Rozszerzenie .html
pozwala nam pisać w pliku korzystając ze składni języka HTML. Rozszerzenie .erb
pozwala nam zawierać w klamrach <%=%>
kod napisany w Ruby.
Zacznijmy od widoku users/index.html.erb
, odpowiada on za wyświetlanie grupy obiektów. Do wyświetlania naszych danych wykorzystamy tabelę.
<h1>Users</h1>
<table>
<tr>
<th>User ID</th>
<th>User Name</th>
</tr>
<% @users.each do |user| %>
<tr>
<td><%= user.id %></td>
<td><%= user.name %></td>
</tr>
<% end %>
</table>
Dla istniejących obiektów klasy User
, będziemy wyświetlać wiersz z jego ID i imieniem.
Musimy jeszcze przekazać nasze obiekty do tej tabeli, więc cofnijmy się kontrolera UsersController
.
def index
@users = User.all
end
W ten sposób pod zmienną @users
, będziemy mieli wszystkie rekordy User
. Tylko, że jeszcze nie mamy jak dodać rekdorów do bazy danych.
CZAS TO ZMIENIĆ!
Dodajmy więc przycisk kierujący nas do tworzenia nowego obiektu.
<%= link_to 'Add New User', new_user_path %>
link_to
jest to metoda pomocnicza, która tworzy nam link z podaną nazwą, do podanego miejsca. new_user_path
jest to metoda pomocnicza, która kieruje nas do akcji new
kontrolera Users
. Dla przypomnienia, dostępne ścieżki możemy podejrzeć używając w terminalu komendy rails routes
.
Teraz po zapisaniu wszystkich plików, wystartowaniu serwera rails s
oraz wejściu na link localhost:3000/users
powinniśmy zobaczyć naszą tablice i link.
Przejdźmy do widoku users/new.html.erb
, który to odpowiada za tworzenie nowego obiektu. Do stworzenia sobie tego formularza wykorzystamy metody które dostarcza nam biblioteka Action View.
<%= form_with model: @object do |form| %>
<%= form.submit %>
<% end %>
Metoda form_with
tworzy formularz dla obiektu podanego w kluczu model
. Aktualny formularz nie udostępnia nam żadnych pól do edycji. W lekcji o modelach stworzyliśmy model o nazwie User
z polem name
. Tak więc dodajmy je do formularza.
<%= form_with model: @object do |form| %>
<%= form.text_field :name %>
<%= form.submit %>
<% end %>
Teraz będziemy mogli edytować pole name
w formularzu. Action View pozwala dodawać nam pola o różnych wartościach.
form.text_area
form.hidden_field
form.password_field
form.number_field
form.range_field
form.date_field
form.time_field
form.datetime_local_field
form.month_field
form.week_field
form.search_field
form.email_field
form.telephone_field
form.url_field
form.color_field
Ostatnią rzeczą jaką musimy zrobić, to powiedzieć naszemu formularzowi jaki w ogóle obiekt chcemy tworzyć. Dlatego musimy wrócić na chwilę do kontrolerów.
Musimy przekazać do widoku obiekt klasy User
, który nie został jeszcze utworzony.
def new
@user = User.new
end
User.new
zainicjalizuje nam obiekt klasy User i poprzez użycie zmiennej instancji będziemy mogli przekazać go do widoku. Jedyne co nam pozostało to zaktualizować nasz formularz by korzystał z naszej nowej zmeinnej.
<%= form_with model: @user do |form| %>
<%= form.text_field :name %>
<%= form.submit %>
<% end %>
Metoda form_with
automatycznie na podstawie podanego obiektu, generuje sobie odpowiedni route
, na który ma się kierować.
Wejdźmy na localhost:3000/users
i klikniemy przycisk Add New User
. Zostaniemy przekierowani na localhost:3000/users/new
i zobaczymy nasz formularz.
Mamy nasz formularz, lecz gdy klikniemy przycisk Submit
to nic się nie zadzieje. A to dlatego, że metoda create
w UsersController
nic nie wykonuje.
def create
@user = User.new(user_params)
if @user.save
redirect_to users_path
else
render :new
end
end
private
def user_params
params.require(:user).permit(:name)
end
Po kolei teraz wytłumaczymy sobie co tutaj się zadziało.
@user = User.new(user_params)
W tej linijce utworzyliśmy sobie nowy obiekt klasy User
, przekazując mu parametry które dostaliśmy z naszego metody user_params
.
private
def user_params
params.require(:user).permit(:name)
end
Metoda user_params
zndajuje się w metodach prywatnych (co oznacza nam private
), która może być wykorzystana tylko i wyłącznie w naszym kontrolerze. W tej metodzie na naszych parametrach wywołujemy require
oraz permit
. Metoda require
wymaga by w naszych parametrach znalazł się podany przez nas klucz (co robi dla nas formularz). Metoda permit
przepuszcza nam tylko i wyłącznie parametry o takich kluczach jakie mu podaliśmy, w tym wypadku name
. Wtedy nasz obiekt zostanie stworzony tylko i wyłącznie z tymi parametrami na jakie pozwoliliśmy.
if @user.save
redirect_to users_path
else
render :new
end
Dalej próbujemy zapisać nasz obiekt. W przypadku sukcesu metoda save
zwróci nam true
, jeżeli zapis się nie uda dostaniemy false
.
Nasz warunek patrzy czy zapis się wykonał czy nie. Jeżeli wszystko poszło pomyślnie zostaniemy przekierowani do widoku index
dla UsersController
. W innym wypadku wyświetlimy znowu nasz formularz. Tutaj jest ważne zawarcie naszego nowego obiektu w zmiennej instancji, byśmy mieli do niej dostęp w widoku oraz by nasz formularz dalej trzymał wpisane przez nas dane.
Kiedy nasz zapis się nie powiedzie? Kiedy dane przez nas dostarczone nie będą spełniały walidacji, które zdefiniowaliśmy w modelu.
I w ten sposób nasz obiekt powinien ukazać się w naszej tabeli.
Zacznijmy od dodania linku do edycji istniejących użytkowników.
<%= link_to 'Add New User', new_user_path %>
<h1>Users</h1>
<table>
<tr>
<th>User ID</th>
<th>User ID</th>
<th>Edit</th>
</tr>
<% @users.each do |user| %>
<tr>
<td><%= user.id %></td>
<td><%= user.name %></td>
<td><%= link_to 'Edit User', edit_user_path(user) %></td>
</tr>
<% end %>
</table>
Tworzenie formularza edycji jest analogiczne do naszego poprzedniego formularza.
Przechodzimy do widoku users/edit.html.erb
i dodajemy tam ten sam formularz.
<%= form_with model: @user do |form| %>
<%= form.text_field :name %>
<%= form.submit %>
<% end %>
Następnie przechodzimy do kontrolera i również przekazujemy obiekt @user
, tylko tym razem znajdziemy ten obiekt po id
, ponieważ został on zapisany do bazy danych.
def edit
@user = User.find(params[:id])
end
Teraz gdy klikniemy w nasz link w tabeli, powinniśmy zostać przenisieni do formularza edycji.
I teraz musimy stworzyć akcję update
w kontrolerze, analogicznie do akcji create
. Tylko w tym wypadku musimy najpierw znaleźć obiekt, który chcemy zaktualizować.
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to users_path
else
render :edit
end
end
Warto zauważyć, że oba formularze przez nas utworzone zawierają ten sam kod. Wyciągnijmy go do jednego pliku by nie powtarzać pisanego kodu.
Stwórzmy plik users/_user.html.erb
. _
przed nazwą oznacza, że tworzymy partial
i w tym partial’u umieścimy nasz formularz.
<%= form_with model: @user do |form| %>
<%= form.text_field :name %>
<%= form.submit %>
<% end %>
Teraz w widokach new
oraz edit
zamieniamy nasze formularze na tę linijkę.
<%= render 'user' %>
Powie to naszym widokom, by dalej kierowały się na ten oto partial.
Dodajmy teraz akcję show
dla naszych obiektów.
Dodajemy link do naszej tabeli.
<%= link_to 'Add New User', new_user_path %>
<h1>Users</h1>
<table>
<tr>
<th>User ID</th>
<th>User Name</th>
<th>Edit</th>
</tr>
<% @users.each do |user| %>
<tr>
<td><%= user.id %></td>
<td><%= link_to user.name, user_path(user) %></td>
<td><%= link_to 'Edit User', edit_user_path(user) %></td>
</tr>
<% end %>
</table>
Tworzymy widok users/show.html.erb
, w którym wyświetlimy imię naszego obiektu.
<%= @user.name %>
Dodajemy akcję w kontrolerze.
def show
@user = User.find(params[:id])
end
Teraz przejdziemy do ostatniej rzeczy, jaką jest usuwanie obiektu.
Zacznijmy od dodania linku do usuwania w naszej tabeli.
<%= link_to 'Add New User', new_user_path %>
<h1>Users</h1>
<table>
<tr>
<th>User ID</th>
<th>User Name</th>
<th>Edit</th>
<th>Delete</th>
</tr>
<% @users.each do |user| %>
<tr>
<td><%= user.id %></td>
<td><%= link_to user.name, user_path(user) %></td>
<td><%= link_to 'Edit User', edit_user_path(user) %></td>
<td><%= link_to 'Delete User', user_path(user), method: :delete %></td>
</tr>
<% end %>
</table>
Podajemy go jak dla show
, tylko określamy go jako metodę delete
.
Następnie dodajemy akcję destroy
w kontrolerze.
def destroy
@user = User.find(params[:id])
if @user.destroy
redirect_to users_path
else
#rozwinięcie tego warunku w następnym rozdziale
redirect_to users_path
end
end
Do naszych akcji możemy dodać powiadomienia.
Wchodząc w plik views/layouts/application.html.erb
i wrzucając pomiędzy tag <body>
następujący kod.
<%= flash[:notice] %>
<%= flash[:alert] %>
Tutaj warto go wrzucić przed <%= yield %>
, aby nasze powiadomienia pokazywały się na samej górze naszej strony.
Przejdźmy teraz do naszej akcji destroy
i dodajmy tam nasze powiadomienia.
def destroy
@user = User.find(params[:id])
if @user.destroy
flash[:notice] = 'User has been destroyed'
redirect_to users_path
else
flash[:alert] = 'Something went wrong'
redirect_to users_path
end
end
Teraz zależnie od powodzenia naszego usuwania wyświetlimy dwa różne powiadomienia.
1. Dodać link do Users na akcji index dla HomeController
2. Stowrzyć formularzę dla Post oraz Comment (wraz z partialami)
3. Dodać do każdej akcji powiadomienia
http://guides.rubyonrails.org/
http://api.rubyonrails.org/
https://guides.rubyonrails.org/form_helpers.html
https://guides.rubyonrails.org/action_controller_overview.html
https://guides.rubyonrails.org/layouts_and_rendering.html
https://api.rubyonrails.org/classes/ActionController/Parameters.html
https://api.rubyonrails.org/classes/ActionDispatch/Flash.html
Przeczytaj również o...
It has already become clear that User Experience (UX) is a key factor in shaping how companies build a business. The customer-centric approach has almost completely replaced […]
What if there was one simple method to find opportunities for improved design, uncover UX problems, and learn about your target users’ behavior and preferences? Would you […]