Updating params in URL after forced/manual input

47 Views Asked by At

I am currently using the Devise user system to set up a model Tutor which is associated to a model Profile whereby Tutor has_one :profile and Profile belongs_to :tutor. Therefore a tutor_id foreign key associates each profile entry to a tutor entry.

In the Profile model, I have the usual Rails REST methods new, edit, show, create and update.

When accessing profile#edit via the URI /profiles/:id/edit, edits are made correctly to the corresponding Tutor model of the profile regardless of what's entered in place of :id in the URL, but it seems kind of awkward for the URL to not reflect this.

So if the tutor with tutor_id: 2 and a profile id: 2 is signed in, accessing the edit action via /profiles/4/edit or /profiles/afjsdjfdsj/edit somehow produces the same result as accessing the proper URL /profiles/2/edit and will still update the correct profile of the tutor.

What I want to do is to update the URL in the address bar to reflect profile id: 2. I've tried using redirect_to in my edit method in my ProfilesController to no avail:

#app/assets/controllers/profiles_controller.rb
def edit
    ...
    @profile = current_tutor.profile
    if @profile.id != params[:id]
        redirect_to edit_profile_path(@profile.id)
    end
    ...
end 

Here is the profiles_controller.rb

# app/assets/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
  before_action :authenticate_tutor!, except: [:show]

  # Everything handled by edit page
  def new
    @tutor = current_tutor

    if (@tutor.profile.nil?)
      @profile = @tutor.build_profile
    else
      @profile = @tutor.profile
      redirect_to edit_profile_path(@profile.id)
    end
  end

  def edit
    @tutor = current_tutor

    if (@tutor.profile.nil?)
      redirect_to new_profile_path
    else
        @profile = @tutor.profile
    end
  end

  def show
    if tutor_signed_in?
      @tutor = Tutor.find(current_tutor.id)
      @profile = Profile.find(@tutor.profile.id)
    else
      @profile = Profile.find(params[:id])
    end
  end

    # POST /tutors
  # POST /tutors.json
  def create
    @profile = current_tutor.build_profile(profile_params)
    if @profile.save
      flash[:success] = "Profile created!"
      redirect_to tutors_dashboard_path
    else
      render 'new'
    end
  end

    # PATCH/PUT /tutors/1
  # PATCH/PUT /tutors/1.json
  def update
    @profile = Profile.find(current_tutor.id)
    if @profile.update(profile_params)
     flash[:success] = "Profile updated!"
     redirect_to tutors_dashboard_path
   else
     render 'edit'
   end
 end

 private 

 def profile_params
   params.require(:profile).permit(:first_name, :last_name, :postal_code, :gender, :dob, :rate, :alma_mater, :major, :degree, :address, :phone_num, :travel_radius, :bio)
 end

end

Here is the routes.rb

Rails.application.routes.draw do

  root 'pages#home'

  get '/about' => 'pages#about'
  get '/contact' => 'pages#contact'
  get '/about-tutors' => 'pages#about_tutors'
  get '/about-students' => 'pages#about_students'

  devise_for :tutors, controllers: {
    confirmations: 'tutors/confirmations',
    passwords: 'tutors/passwords',
    registrations: 'tutors/registrations',
    sessions: 'tutors/sessions'
  }

  get '/tutors/dashboard' => 'tutors#dashboard'

  resources :profiles
end
1

There are 1 best solutions below

0
On BEST ANSWER

After MUCH frustration, I figured out that params[:id] returns a string and NOT an integer, therefore to_i is required to compare the two.

Correct code:

#app/assets/controllers/profiles_controller.rb
def edit
    ...
    @profile = current_tutor.profile
    if @profile.id != params[:id].to_i   # convert params[:id] to an integer value
        redirect_to edit_profile_path(@profile.id)
    end
    ...
end