Theo Cerutti
Theo Cerutti

Reputation: 970

Rails Devise : how to update user by id?

I would like to update a user by id. I don't know if I need to create another function or the devise update use function.

This doesn't work, it updates my current user instead of the user of data id (I update my user by axios api call):

const data = {
  user = {
    first_name: 'firstNameChanged'
    id: 10
  }
};
axios.put('http://localhost:3000/users', data).then((res) => {
  console.log('user updated');
});

EDIT:

route.rb

  devise_for :users, defaults: { format: :json }, controllers: { registrations: "registrations" }
  devise_scope :user do
    delete 'users/:id', to: 'registrations#destroy_by_id', defaults: { format: :json } # custom delete_by_id
  end

  rake routes

        new_user_session GET    /users/sign_in(.:format)                                                       devise/sessions#new {:format=>:json}
            user_session POST   /users/sign_in(.:format)                                                       devise/sessions#create {:format=>:json}
    destroy_user_session DELETE /users/sign_out(.:format)                                                      devise/sessions#destroy {:format=>:json}
       new_user_password GET    /users/password/new(.:format)                                                  devise/passwords#new {:format=>:json}
      edit_user_password GET    /users/password/edit(.:format)                                                 devise/passwords#edit {:format=>:json}
           user_password PATCH  /users/password(.:format)                                                      devise/passwords#update {:format=>:json}
                         PUT    /users/password(.:format)                                                      devise/passwords#update {:format=>:json}
                         POST   /users/password(.:format)                                                      devise/passwords#create {:format=>:json}
cancel_user_registration GET    /users/cancel(.:format)                                                        registrations#cancel {:format=>:json}
   new_user_registration GET    /users/sign_up(.:format)                                                       registrations#new {:format=>:json}
  edit_user_registration GET    /users/edit(.:format)                                                          registrations#edit {:format=>:json}
       user_registration PATCH  /users(.:format)                                                               registrations#update {:format=>:json}
                         PUT    /users(.:format)                                                               registrations#update {:format=>:json}
                         DELETE /users(.:format)                                                               registrations#destroy {:format=>:json}
                         POST   /users(.:format)                                                               registrations#create {:format=>:json}
                         DELETE /users/:id(.:format)                                                           registrations#destroy_by_id {:format=>:json}

thanks !

Upvotes: 0

Views: 2265

Answers (2)

max
max

Reputation: 101821

Devise actually only has routes and controllers to modify your own account. If you want an interface to administrate other users you are best off just creating it yourself or finding an existing implementation.

While its certainly possible to shoehorn this functionality into Devise its just going to get messy and violates the SRP as your RegistrationsController is no longer just responsible for handling user registration but also administrating other users.

You can pretty much just work off the Rails scaffolds (rails g scaffold users --skip-migration --skip-model) as its not really that different from CRUD'ing any other resource. What you really need is just something like:

# routes.rb
resources :users, except: [:new, :create]
# This controller is for administrating other users
class UsersController < ApplicationController
   # ensures that there is a logged in user
   # you should also implement authorization that ensures that the user is allowed to administrate other users
   before_action :authenticate_user! 
   # sets the user to be acted upon
   before_action :set_user, only: [:show, :edit, :update, :destroy]

   # PUT|PATCH /users/1
   def update
     if @user.update(user_params)
       head :ok
     else
       head :unprocessable_entity
     end
   end

   # ...
   private

   def set_user 
     @user = User.find(params[:id])
   end

   def user_params
     params.require(:user).permit(:first_name)
   end
end
const data = {
  user = {
    first_name: 'firstNameChanged'
  }
};
axios.put('http://localhost:3000/users/10', data).then((res) => {
  console.log('user updated');
});

Upvotes: 1

Michael De Silva
Michael De Silva

Reputation: 3818

Check your rake routes | grep user and you'll find there is an entry under PUT. The path would look like /users/:id, that's your first mistake. This would also map (typically) to a UsersController#update action.

You can then access the id that's passed via the params (use strong params too) and find your user with User.find_by(id: permitted_params[:id]). You can create a private method called permitted_params along the lines of

def permitted_pararms
  params.permit(:id)
end

Upvotes: 0

Related Questions