marg08 marg08 - 8 days ago 7
Ruby Question

Can't redirect Devise sign page to show profile

I'm hoping someone can help. I am using the Devise gem for registering and signing in users. I have a Profile controller. When an existing user logs in, I want them to be diverted to the Profile's show.html.erb page in order to view their profile. I would expect this would be done under the Sessions controller but it doesn't seem to do anything

The Sessions controller code is:

class Registrations::SessionsController < Devise::SessionsController
# before_action :configure_sign_in_params, only: [:create]

protected
def after_sign_in_path_for(resource)
profile_path(resource)
end


However, when a user registers, the redirect works successfully under the Registrations controller below:

class RegistrationsController < Devise::RegistrationsController
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]

protected
def after_sign_up_path_for(resource)
new_profile_path(resource)
end.


I also want to have a link to the users Profile page when they are logged in but when I do it throws up the following error

application.html.erb code for the link is below (I have tried a number of different variables in place of the '@profile' but with no success)

<li><%= link_to 'Show Profile', profile_path(@profile), :class => 'navbar-link' %></li>


The error I receive is:

ActionController::UrlGenerationError in Profiles#index

No route matches {:action=>"show", :controller=>"profiles", :id=>nil} missing required keys: [:id]


My routes (which I'm not sure are setup correctly:

Rails.application.routes.draw do

resources :profiles
get 'profiles/:id', to: 'profiles#show'
get '/profiles/new' => 'profiles#new'
get '/profiles/edit' => 'profiles#edit'
get '/profiles/index' => 'profiles#index'

root to: 'pages#index'

devise_for :users, :controllers => { :registrations => "registrations" }


Lastly, my Profile controller:

class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]

def index
@search = Profile.search(params[:q])
@profiles = @search.result(distinct: true)
end

def show
@profile = Profile.find(params[:id])
end

def new
@profile = Profile.new
end

def create
@profile = Profile.new(profile_params)

respond_to do |format|
if @profile.save
format.html { redirect_to @profile, notice: 'Your Profile was successfully created' }
format.json { render :show, status: :created, location: @profile }
else
format.html { render :new }
format.json { render json: @profile.errors, status: :unprocessable_entry }
end
end
end

def edit
@profile = Profile.find(params[:id])
end

def update
respond_to do |format|

if @profile.update(profile_params)
format.html { redirect_to @profile, notice: 'Profile was successfully updated.' }
format.json { render :show, status: :ok, location: @profile }
else
format.html { render :edit }
format.json { render json: @profile.errors, status: :unprocessable_entity }
end
end
end

def destroy
@profile.destroy

respond_to do |format|
format.html { redirect_to profile_url, notice: 'Profile was successfully destroyed.' }
format.json { head :no_content }
end
end

def set_profile
@profile = Profile.find(params[:id])
end

private
def profile_params
params[:profile][:user_id] = current_user.id
params.require(:profile).permit(:full_name, :contact_number, :location, :makeup_type, :bio, :user_id, :image)
end
end


Any help is most appreciated.

Answer

In your application controller you want something like this

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def after_sign_in_path_for(user)
    profile_path(current_user)
  end
  #user is the model name for example that you created with devise

end