Jason Bourne Jason Bourne - 12 days ago 5
reST (reStructuredText) Question

Ruby on Rails: Adding Additional RESTFUL Actions

In my rails app I would like to have two patch methods for updating the users profile.

First, I will have an 'account_settings' GET request, which will use the standard edit/update REST action to update certain parameters. Then, I would like to have an additional 'edit_profile' and 'update_profile' actions to get a page that will allow the user to update different user attributes. Here's how it looks in my

users_controller.rb
for a better idea:

#For account settings page

#This is for the account settings page
#(only changing email and password)
def edit
@user = User.find(params[:id])
render 'edit'
end

def update
@user = User.find(params[:id])
respond_to do |format|
if @user.update_attributes(account_settings_params)
flash.now[:success] = "Your settings have been successfully updated."
format.html {redirect_to @user}
else
format.html {redirect_to edit_user_path}
flash[:error] = "Please be sure to fill out your email, password, and password confirmation."
end
end
end

def edit_profile
@user = User.find(params[:id])
render 'edit_profile'
end

#For update profile
def update_profile
@user = User.find(params[:id])
respond_to do |format|
if @user.update_attributes(user_profile_params)
flash.now[:success] = "Your profile has been updated."
format.html {redirect_to @user}
else
format.html {redirect_to edit_profile_user_path}
flash[:error] = "Please be sure to fill out all the required profile form fields."
end
end
end


private

def account_settings_params
params.require(:user).permit(:email, :password, :password_confirmation)
end

def user_profile_params
params.require(:user).permit(:name, :about_me, :location, :image_url)
end


Selection from my current routes.rb :

#Account Settings Just for Email and Password
get 'account_settings' => 'users#edit'
patch 'settings' => 'users#update'
resources :users do
member do
get :edit_profile
put :update_profile
end
end


Results of rake routes:

edit_profile_user GET /users/:id/edit_profile(.:format) users#edit_profile
update_profile_user PATCH /users/:id/update_profile(.:format) users#update_profile
users 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
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy


My navbar partial:

-if logged_in?
-# Logged in links
%li
=link_to 'Logout', logout_path, method: :delete
%li
=link_to 'Account Settings',edit_user_path(@current_user)
%li
=link_to 'Edit My Profile', edit_profile_user_path(@current_user)
%li
=link_to 'View My Profile', user_path(@current_user)
%li
=link_to 'Members', users_path


On the edit_profile page, my form looks like this:

=form_for @user, path: update_profile_user_path(@user) do |f|


With my current implementation, visiting the edit_profile page and posting the form will lead back to the regular edit page with my rails server saying that the parameters were unpermitted. However, as you can see in my update_profile method in my controller, the controller method for update_profile accepts
user_profile_params
rather than the
account_settings_params
. Any insight onto why it might be doing this?

Answer

A few notes:

  • You don't need render "edit_profile" because that is done by default
  • You don't need to overwrite the edit route
  • I'd strongly suggest actually having a separate Profile controller, instead of trying to hack it in as extra actions on user.

That being said, the routes look like

resources :users do
  member do
    get :edit_profile
    patch :update_profile
  end
end

then your link would be to users/1/edit_profile (link_to "edit", edit_profile_path(@user)) and the form would be to <%= form_for @user, path: update_user_path(@user) %>

Comments