Частичные проверки Rails в зависимости от контроллера

Я использую devise для регистрации пользователей, что означает, что по умолчанию новый пользователь регистрируется через Registrations_controller. Итак, нажав кнопку «Зарегистрироваться», пользователь перенаправляется на new_user_registration path.

Однако моя регистрационная форма состоит из двух шагов. На первом этапе (new_user_registration) я запрашиваю имя и пароль. На втором этапе (users_controller), когда пользователь сохраняется, я запрашиваю адрес. Это я делаю с драгоценным камнем мастера:

    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

Итак, это своего рода частичные проверки, но я не могу проверить в зависимости от шага, так как первая часть моей формы обрабатывается через контроллер регистрации. Однако вторая часть находится в файле users_controller. Здесь все усложняется, и я хотел бы знать, могу ли я проверить в зависимости от контроллера. Нравиться:

validates :first_name, presence: true, if: -> { new_user_registration_path }
validates :last_name, presence: true, if: -> { new_user_registration_path }
validates :street, presence: true, if: -> { new_user_path }

Я знаю, в таком виде это не имеет смысла, но, может быть, это поможет понять мои мысли. Кроме того, возможно, я могу работать с чем-л. нравится:

validates :first_name, presence: true, if: -> { @user.save }
validates :last_name, presence: true, if: -> { @user.save }
validates :street, presence: true, if: -> { @user.update}

В общем, при создании нового пользователя я бы проверял наличие имени и пароля. И когда затем добавлю адрес (это действие обновления для пользователя), я проверю, присутствует ли адрес. Кто-нибудь сталкивался с такими формами?

Еще мысль, может быть, я могу пропустить контроллер регистраций, перенаправив пользователя напрямую и создав два шага для частичных проверок? Но поскольку я работаю с разработкой, я не знаю, смогу ли я просто пройти через контроллер пользователей, пропустив путь new_user_registration. Сделал, как советовали на злом туториале, но все равно попал в контроллер регистраций:

 def create
      super
  end
 def update
      super
  end

Спасибо!


person Katharina Schreiber    schedule 21.01.2020    source источник


Ответы (2)


Лучшее решение проблемы такого типа — использование объектов формы. См. этот пример и реформа драгоценного камня.

С объектами формы каждая HTML-форма обрабатывается через объект формы. В вашем примере у вас может быть форма «Регистрация пользователя» и форма «Обновление пользователя». Ключевым моментом является то, что проверка выполняется формой, а не моделью. Таким образом, проверка относится к текущему вводу формы, и вы избегаете проблем с классификацией правил проверки.

person ReggieB    schedule 21.01.2020
comment
Спасибо. Означает ли это на самом деле, что мне нужна модель адреса, которая, по сути, является моим вторым шагом в форме? - person Katharina Schreiber; 21.01.2020
comment
Это зависит. Если у пользователя может быть более одного адреса, тогда да, вам нужна модель адреса. Если у пользователя когда-либо был только один адрес, вы можете обойтись без атрибутов адреса в пользовательской модели. Также имеет смысл иметь отдельный адресный объект, если имеется много специфичного для адреса кода. - person ReggieB; 21.01.2020
comment
Я нашел гораздо более простое решение, возможно, интересное для вас: см. Ниже - person Katharina Schreiber; 21.01.2020

Это так просто:

validates :first_name, presence: true, :on => :create
validates :last_name, presence: true, :on => :create
validates :street, presence: true, :on => :update
validates :house_number, presence: true, :on => :update
validates :city, presence: true, :on => :update
validates :zip_code, presence: true, :on => :update

Ясно, что «Регистрация» создает пользователя. И wizard_steps просто обновляет пользователя. Итак, для этого простого примера это работает отлично и вызывает ошибки проверки в соответствии с действием контроллера.

person Katharina Schreiber    schedule 21.01.2020
comment
Это не отличное решение. Он привязывает модель к входной последовательности и означает, что проверка некоторых атрибутов пропускается при последующих действиях (например, если пользователь хочет позже обновить свое имя first_name). Объекты формы — гораздо более гибкое и масштабируемое решение. - person ReggieB; 21.01.2020