Tìm hiểm gem Wicked trong Rails
Bài đăng này đã không được cập nhật trong 8 năm
1. Giới thiệu
Trong Rails, rất nhiều trường hợp chúng ta phải phá vỡ RESTful để thực hiện step by step một công việc nào đó. (Ví dụ: Khi muốn tạo mới một object bạn muốn có thể preview thông tin của object đó trước khi save lại. Trong trường hợp này bạn phải tạo thêm một hàm preview trong controller). Wicked
giúp chúng tao thu gọn những hàm không cần thiết một cách linh hoạt để controller luôn thỏa mãn RESTful. Hãy cũng đọc qua bài hướng dẫn này để hiểu thêm cách hoạt động của nó.
2. Cài đặt
Thêm vào Gemfile
gem “wicked”
Run bundle install
Giờ chúng ta sẽ ví dụ trên controller after signup
- Tạo controller:
rails g controller after_signup
- Thêm route vào file
config/routes.rb
:
resource :after_signup
- Include
Wicked::Wizard
vào controller trên
class AfterSignupController < ApplicationController
include Wicked::Wizard
steps :confirm_password, :confirm_profile, :find_friends
end
Một cách khai báo khác bằng cách thừa kế Wicked::WizardController
:
class AfterSignupController < Wicked::WizardController
steps :confirm_password, :confirm_profile, :find_friends
end
wizard
được dùng để gọi step trong hàm show
, bạn có thể tùy chỉnh logic trong hàm show tùy vào từng trường hợp như ví dụ bên dưới đây.
class AfterSignupController < ApplicationController
include Wicked::Wizard
steps :confirm_password, :confirm_profile, :find_friends
def show
@user = current_user
case step
when :find_friends
@friends = @user.find_friends
end
render_wizard
end
end
Bạn cần phải gọi render_wizard
ở cuối của hàm để gọi được view tương ứng.
Mặc định wizard
sẽ render view cùng tên với step trong controller. Vậy với AfterSignupController
bạn sẽ có thư mục view tương ứng là /views/after_signup/
. Nếu gọi step :confirm_password thì wizard
sẽ render views/after_signup/confirm_password.html.erb
Ở view bạn có thể suer dụng helper để chuyển tới bước tiếp theo:
<%= link_to 'skip', next_wizard_path %>
Bạn cũng có thể chỉ định chính xác step mà mình muốn chuyển đến bằng cách sử dụng wizard_path
helper:
<%= link_to 'skip', wizard_path(:find_friends) %>
Một ví dụ khác về wicked
trong hàm update
class AfterSignupController < ApplicationController
include Wicked::Wizard
steps :confirm_password, :confirm_profile, :find_friends
def update
@user = current_user
case step
when :confirm_password
@user.update_attributes(params[:user])
end
sign_in(@user, bypass: true) # needed for devise
render_wizard @user
end
end
Ở đây chúng ta sử dụng render_wizard @user
. Khi sử dụng như thế này controller sẽ chuyển đến bước tiếp theo nếu @user save thành công hoặc chuyển đến bước trước nếu thất bại.
CHú ý : render_wizard
bao gồm cả save đối tượng. Điều đó có nghĩa rằng với ví dụ bên trên đối tượng sẽ lưu lại hai lần đồng nghĩa là nếu có callback sẽ cũng sẽ bị gọi hai lần. Vì vậy trong trường hợp này chúng ta nên sử dụng assign_attributes
thay cho update_attributes
sẽ chính xác hơn.
Để gọi update cho user chỉ đơn giản submit form với method PUT tới chính xác url:
<%= form_for @user, url: wizard_path, method: :put do |f| %>
<%= f.password_field :password %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Change Password" %>
<% end %>
Hãy nhơ khai báo method: :put
ở đây vì nếu quên điều này bạn sẽ nhận được một cảnh báo rằng không tìm thấy action create
nào hoặc "no route found for POST.
Ngoài ra trong controller nếu bạn muốn bỏ qua một step nào đó thì chỉ cần gọi hàm skip_step
def show
@user = current_user
case step
when :find_friends
if @user.has_facebook_access_token?
@friends = @user.find_friends
else
skip_step
end
end
render_wizard
end
3. Danh sách method
View/URL Helpers:
wizard_path # lấy path hiện thời
wizard_path(:specific_step) # path tới :specific_step
next_wizard_path # path tới step kế tiếp
previous_wizard_path # path tới step trước đó
Controller
steps :first, :second # set thứ tự của các step
step # gọi step hiện tại
next_step # gọi step kế tiếp
previous_step # gọi step trước đó
skip_step # bỏ qua step
jump_to(:specific_step) # gọi :specific_step
render_wizard # Renders step hiện tại
render_wizard(@user) # render step kế tiếp nếu @user lưu thành công
wizard_steps # list các step
4. Tổng kết
Trên đây là những hướng dẫn cơ bản để sử dung gem Wicked
tạo các step trong controller. Các bạn có thể tham khảo thêm tại : gem Wicked.
Chúc các bạn thành công
All rights reserved