Andrew Makarov
Andrew Makarov

Reputation: 35

Rails - is it possible to redirect to a custom path with params?

So I am making an authorisation system. A new registration page is set to be '/signup'. If registration is invalid (username has already been taken, password too short), I want to show the errors. When I do it like this:

@user = User.create(user_params)
    if @user.save
        session[:user_id] = @user.id
        redirect_to stories_path, notice: "Thanks for registration!"
    else
        render 'new'
    end

it works, but it renders in '/users' instead of '/signup'. And when instead of

render 'new'

I write

redirect_to '/signup'

it redirects, but errors are not shown. Is it possible to redirect to '/signup' and keep the errors?

user.rb:

class User < ActiveRecord::Base
    has_secure_password
    validates :username, presence: true, :uniqueness => { :case_sensitive => false }
    validates :password, presence: true, :length => {minimum: 6}
end

users_controller.rb:

class UsersController < ApplicationController
    def new
        @user = User.new
    end

    def create
        @user = User.create(user_params)
        if @user.save
            session[:user_id] = @user.id
            redirect_to stories_path, notice: "Thanks for registration!"
        else
            render 'new'
        end
    end

    private

    def user_params
        params.require(:user).permit(:username, :password)
    end
end

new.html.erb:

<h3>New registration</h3>

<%= simple_form_for @user do |f| %>
   <div> <%= f.input :username %>
    <%= f.error :username %></div>
    <div><%= f.input :password %>
    <%= f.error :password %></div>

    <%= f.button :submit %>
<% end %>

and routes.rb:

Rails.application.routes.draw do
  root 'stories#index'
  resources :stories
  resources :users
  get 'signup' => 'users#new'
end

Upvotes: 3

Views: 2535

Answers (1)

Farkhat Mikhalko
Farkhat Mikhalko

Reputation: 3665

it works, but it renders in '/users' instead of '/signup'

It's normal behavior. The /signup page is the result of new action from UsersController. This page contains form. After submitting this form, data goes to create action from the same controller, but via POST method.

If validation will be failed controller will render :new template, as you remember create action has /users link. So you will see :new template in /users link.

Here is route map for UsersController:

          GET    /users(.:format)                users#index
          POST   /users(.:format)                users#create
 new_user GET    /users/new(.:format)            users#new
edit_user GET    /users/:id/edit(.:format)       users#edit
     user GET    /users/:id(.:format)            users#show
          PUT    /users/:id(.:format)            users#update
          DELETE /users/:id(.:format)            users#destroy

To achieve your requirements you can add route to routes.rb. And change the url in form.

Something like this:

post 'signup` => 'users#create`

And in form:

<%= simple_form_for(@user, url: HERE_IS_SIGNUP_PATH) do |f| %>

Upvotes: 1

Related Questions