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
After MUCH frustration, I figured out that
params[:id]
returns a string and NOT an integer, thereforeto_i
is required to compare the two.Correct code: