Sejak memasang "dark" theme, saya cenderung menjadi malas menulis. Untuk sementara, dark theme saya disable dulu yaa. Terima kasih (^_^) (bandithijo, 2024/09/15) ●
Prerequisite
Ruby 2.6.3
Rails 5.2.3
PostgreSQL 11.5
Prakata
Mengawali tahun 2020 ini, saya mencatat mengenai Ruby on Rails.
Kali ini mengenai bagaimana cara memberikan user experience flow yang baik dengan web aplikasi yang menggunakan form saat pengguna belum melakukan authentication.
Permasalahan
Dalam mengisi form, misalkan form pemesanan (order), yang memiliki banyak inputan data, tentunya pengguna akan merasa kesal, apabila sudah memasukkan banyak data, namun saat menekan tombol submit, dan harus melakukan sign in atau sign up terlebih dahulu, setelah itu, data yang pengguna masukkan pada order form tadi sudah menghilang. Artinya, pengguna harus memasukkan kembali data-data yang sudah ia masukkan sebelumnya.
User experience flow di atas, tentunya akan membuat user merasa kesal.
Penyelesaian Masalah
Kebetulan, web aplikasi kali ini menggunakan Devise gem untuk menghandle proses authentication.1
Saya dapat memanfaatkan helper-helper module yang sudah disediakan oleh Devise.
Seperti, untuk membawa user kembali ke halaman sebelumnya, dengan stored_location_for
dari Devise::Controllers::StoreLocation
.
Untuk menyelesaikan permasalahan di atas, saya akan memodifikasi controller-controller yang menghandle proses-proses di atas.
Proses di atas terdiri dari:
- Order, yang dihandle oleh
Users::OrderExperiencesController#create
- Sign In, yang dihandle oleh
Users::SessionsController
- Sign Out, yang dihandle oleh
Users::RegistrationsController
Bagaimana memertahankan data yang sudah dimasukkan sebelumnya pada Order form?
Untuk membuat data yang ada pada form menjadi persistent, saya akan memanfaatkan session.2 Kemudian, setelah user melakukan authentication, session akan di-passing ke dalam variable dan akan dikosongkan.
Order Experiences Controller
Karena proses order experience ini di-handle oleh action :create
, maka saya perlu memodifikasi isi dari action ini.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# frozen_string_literal: true
class Users::OrderExperiencesController < ApplicationController
# pastikan untuk tidak memfilter action :create, karena akan dihandling oleh
# redirect rule yang akan dibuat
before_action :authenticate_user!, except: [:create]
def create
# mengecek apakah pengunjung sudah sign in/sign up
if current_user.nil?
# menyimpan data dari form ke dalam session, yang akan digunakan setelah login/register
session[:order] = params
# redirect ke user login/register page
redirect_to new_user_session_path
else
# jika user sudah login, diproses seperti biasa
order = current_traveler.orders.create(order_params)
redirect_to users_order_experience_path(order.id)
end
end
# ...
# ...
private
def order_params
params.require(:order).permit(
:trip_date, :time_slot, :total_traveler, :experience_id,
traveler_attributes: [:id, :full_name, :email, :phone]
)
end
end
Pastikan pada callback before_action :authenticate_user!
, buat pengecualian untuk action :create
.
Selanjutnya, tinggal memodifikasi controller yang menghandle proses login/register.
Sessions & Registrations Controller
Kedua controller ini adalah controller yang digenerate oleh Devise.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# frozen_string_literal: true
class Users::SessionsController < Devise::SessionsController
# ...
# ...
# ...
protected
# ...
# ...
# path yang akan dituju setelah sign in
def after_sign_in_path_for(resource_or_scope)
# memeriksa apakah ada data order yang tersimpan pada session
if session[:order].present?
# membuat order dengan data yang tersimpan pada session
order = current_traveler.orders.create(session[:order]["order"])
# mengosongkan session
session[:order] = nil
# redirect ke halaman order
users_order_experience_path(order.id)
else
# jika tidak ada data order yang tersimpan pada session
stored_location_for(resource_or_scope) || super
end
end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# frozen_string_literal: true
class Users::RegistrationsController < Devise::RegistrationsController
# ...
# ...
# ...
protected
# ...
# ...
# path yang akan dituju setelah sign up
def after_sign_up_path_for(resource_or_scope)
# memeriksa apakah ada data order yang tersimpan pada session
if session[:order].present?
# membuat order dengan data yang tersimpan pada session
@order = current_traveler.orders.create(session[:order]["order"])
# mengosongkan session
session[:order] = nil
# redirect ke halaman order
users_order_experience_path(@order.id)
else
# jika tidak ada data order yang tersimpan pada session
stored_location_for(resource_or_scope) || super
end
end
# ...
# ...
end
Selesai!
Mungkin pada kesempatan yang lain, akan saya buatkan reponya.
Mudah-mudahan bermanfaat.
Terima kasih.
(^_^)
Referensi
-
How To: Redirect back to current page after sign in, sign out, sign up, update
Diakses tanggal: 2020/01/01 -
Action Controller Overview > Session
Diakses tanggal: 2020/01/01 -
blog.justinthiele.com/retaining-form-data-through-a-login-process-a
Diakses tanggal: 2020/01/01
Lisensi
Atribusi-NonKomersial-BerbagiSerupa 4.0 Internasional (CC BY-NC-SA 4.0)
Penulis
My journey kicks off from reading textbooks as a former Medical Student to digging bugs as a Software Engineer – a delightful rollercoaster of career twists. Embracing failure with the grace of a Cat avoiding water, I've seamlessly transitioned from Stethoscope to Keyboard. Armed with ability for learning and adapting faster than a Heart Beat, I'm on a mission to turn Code into a Product.
- Rizqi Nur Assyaufi