Я пытаюсь реализовать ту же концепцию, которую Райан Бейтс обсуждал в своем Railscast здесь: http://railscasts.com/episodes/217-multistep-forms в моей форме регистрации пользователей.
В основном 3 шага следующие:
Шаг 1. Заполните данные пользователя
Шаг 2: Перейдите на внешний URL-адрес, чтобы завершить платежные реквизиты, после чего они будут перенаправлены обратно к этой форме регистрации пользователя, когда они закончат.
Шаг 3: Подтвердите и отправьте данные
В настоящее время мой обходной путь - сначала создать пользователя, а затем перенаправить на внешний URL-адрес для завершения платежа после @ user.save, но я хотел бы использовать эту многошаговую форму, чтобы предотвратить сохранение пользователя, если он не завершит оплата первая.
Был бы признателен, если бы вы указали мне направление ... спасибо.
UPDATE:
Мой пользовательский контроллер:
def new
session[:user_params] ||= {}
if params[:plan_id].present?
@user = User.new(session[:user_params] && :plan_id => params[:plan_id])
else
@user = User.new(session[:user_params])
end
@user.current_step = session[:user_step]
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @user }
end
end
def create
session[:user_params].deep_merge!(params[:user]) if params[:user]
@user = User.new(session[:user_params])
@user.current_step = session[:user_step]
if @user.valid?
if params[:back_button]
@user.previous_step
elsif @user.last_step?
@user.save
elsif @user.billing_step?
@user.next_step
redirect_to("external.com") and return
else
@user.next_step
end
session[:user_step] = @user.current_step
end
if @user.new_record?
render "new"
else
session[:user_step] = session[:user_params] = nil
flash[:success] = "User saved"
redirect_to dashboard_url
end
end
Моя пользовательская модель:
validates_presence_of :username, :first_name, :last_name, :if => lambda { |u| u.current_step == "initial" }
attr_writer :current_step
def current_step
@current_step || steps.first
end
def steps
%w[initial billing confirmation]
end
def next_step
self.current_step = steps[steps.index(current_step)+1]
end
def previous_step
self.current_step = steps[steps.index(current_step)-1]
end
def first_step?
current_step == steps.first
end
def last_step?
current_step == steps.last
end
def billing_step?
current_step == steps.second
end
Мой новый пользовательский просмотр:
<%= form_for @user, :url => {:action => :create, :plan_id => params[:plan_id] } do |f| %>
<% if @user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= render "#{@user.current_step}_step", :f => f %>
<% end %>
Проблема в пользовательском контроллере с @ user.billing_step?
после нажатия кнопки отправки мне необходимо выполнить следующее: 1.) добавить шаг (используя @ user.next_step) И 2.) перенаправить на внешний URL-адрес.
Таким образом, когда пользователи возвращаются к «пользователи / новые», они уже находятся на последнем этапе подтверждения.
Если я не добавлю команду «and return» в конце перенаправления, я получу ошибку «Render и / или redirect были вызваны несколько раз в этом действии». Если я это сделаю, Rails не добавит новый шаг и вернет меня к этапу биллинга (шаг 2) всего этого.