У меня есть многошаговая форма, которую я создал с помощью мастера. По сути, первым теплом формы является user / sign_up - что, на мой взгляд, еще не шаг. После нажатия кнопки регистрации пользователь переходит к «реальному» первому шагу, который является :address.
class UserStepsController < ApplicationController
include Wicked::Wizard
steps :address
def show
@user = current_user || User.from_omniauth(request.env["omniauth.auth"])
render_wizard
end
def update
@user = current_user || User.from_omniauth(request.env["omniauth.auth"])
@user.update!(user_params)
render_wizard @user
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :street, :house_number, :city, :zip_code)
end
def redirect_to_finish_wizard(options = nil, params = nil)
redirect_to new_user_profile_path(current_user)
end
end
Это, по сути, конец формы. Все сохраняется для пользователя. Теперь я застрял с проверками.
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:omniauthable, omniauth_providers: %i[facebook]
has_one :profile, dependent: :destroy
after_create :create_profile
accepts_nested_attributes_for :profile
validates :first_name, presence: true
validates :last_name, presence: true
validates :street, presence: true
validates :house_number, presence: true
validates :city, presence: true
validates :zip_code, presence: true
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0, 20]
name = auth.info.name
user.first_name = name.split(" ")[0]
user.last_name = name.split(" ")[1]
end
end
end
Я бы хотел работать с условными валидациями в моей модели и проверять присутствие только на определенном этапе. Это должно быть легко, так как теоретически у меня есть только один шаг - адрес. Все, что я нахожу в inte rnet, слишком сложно. Вопрос в том, должен ли я как-то изменить user / sign_up на первый шаг в форме, а адрес будет вторым шагом? Или это нормально? И если да, могу ли я просто добавить операторы «if» к атрибутам адреса в моих проверках, каким-то образом определяя, каков шаг адреса? Будет ли это работать так?
def on_address_step?
wizard.steps = wizard.steps.first
end
Или как мне это определить? Тогда валидации будут выглядеть так:
validates :first_name, presence: true
validates :last_name, presence: true
validates :street, presence: true, if: :on_address_step?
validates :house_number, presence: true, if: :on_address_step?
validates :city, presence: true, if: :on_address_step?
validates :zip_code, presence: true, if: :on_address_step?
Это, конечно, не так просто. На данный момент это тоже не работает. Как мне нужно изменить это? Спасибо. PS: вот и мой пользовательский контроллер:
class UsersController < ApplicationController
def index
@users = User.all
end
def new
@user = User.new
end
def create
@user = User.new(params[:user])
if @user.save
session[:user_id] = @user.id
redirect_to user_steps_path
else
render :new
end
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :street, :house_number, :city, :zip_code)
end
end