Tìm hiểm gem Wicked trong Rails
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 ...
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