0
votes

I applied Devise in two models: Guardian and User.

Taking User for instance:

Controller (users/registrations_controller.rb):

class Users::RegistrationsController < Devise::RegistrationsController
  layout 'devise', only: [:new, :create]
  before_action :configure_sign_up_params, only: [:create]

  # GET /resource/sign_up
  def new
    super
  end

  # POST /resource
  def create
    if !params[:user][:birth_year].blank? && !params[:user][:birth_month].blank? && !params[:user][:birth_day].blank?
      params[:user][:birthday] = Time.new(params[:user][:birth_year], params[:user][:birth_month], params[:user][:birth_day], utc_offset="+08:00")
    end
    @user = User.new params.require(:user).permit(:username, :nickname, :birthday, :password, :email).merge(locale: locale)
    if verify_rucaptcha?(@user) && @user.save
      sign_in @user
      redirect_to new_guardian_registration_path
    else
      render :new
    end
  end

  protected

    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :username, :birth_year, :birth_month, :birth_day, :terms])
  end
end

Routes (config/routes.rb):

Rails.application.routes.draw do

  ...

  devise_for :users, controllers: {
    sessions: 'users/sessions',
    registrations: 'users/registrations'
    }, path_names: {
    sign_in: 'login',
    sign_out: 'logout',
    sign_up: 'signup'
    }
    ... 
end

When failure to create new user, it will render :new action and to pass inputted parameters in the new form (page). However, its display url (in browser) changed from 'localhost:3000/users/signup' to 'localhost:3000/users'. It's work but if refresh page, Routing error will be generated: 'No route matches [GET] "/users"'.

I tried to change "render :new" to "redirect_to new_user_registration_path", the display url (in browser) is OK ('localhost:3000/users/signup') but the form status and inputted parameters will not passed correctly.

1
What you are trying to do might seem like a good idea, but its not how Rails or the browser works. When you submit a form in rails what is rendered is the result of performing a POST/PATCH action. Not a resource that should cached or that should even have a unique url. When you refresh it should instead send a GET request to /users. This is a measure to avoid the user inadvertently resending a non-safe request. - max
The browser does not let you alter the location either without redirecting (except via pushState in javascript). - max

1 Answers

0
votes

I found an alternative way.

1) To submit the form remotely (data-remote: true);

2) Create a "create.js.erb" in "views\users\registrations" folder;

<% if resource.errors.empty? %>
  <% flash[:notice] = t('devise.sessions.signed_in') %>
  Turbolinks.visit('<%= after_sign_up_url %>');
<% else %>
  $('#new_user .alert').remove();
  $('#new_user').prepend('<%= j render("shared/form_error_messages", target: resource) %>');
<% end %>