Rails 设计:如何通过 id 更新用户?

Rails Devise : how to update user by id?

我想通过 ID 更新用户。 我不知道我是否需要创建另一个功能或设计更新使用功能。

这不起作用,它更新我当前的用户而不是数据 ID 的用户(我通过 axios api 调用更新我的用户):

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

编辑:

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}

谢谢!

检查您的 rake routes | grep user,您会发现 PUT 下有一个条目。该路径看起来像 /users/:id,这是您的第一个错误。这也会(通常)映射到 UsersController#update 操作。

然后您可以访问通过参数(也使用强参数)传递的 id 并使用 User.find_by(id: permitted_params[:id]) 找到您的用户。您可以按照

行创建一个名为 permitted_params 的私有方法
def permitted_pararms
  params.permit(:id)
end

Devise其实只有routes和controller可以修改自己的账号。如果你想要一个界面来管理其他用户,你最好自己创建它或找到一个现有的实现。

虽然将此功能硬塞进 Devise 中当然是可能的,但它只会变得混乱并违反 SRP,因为您的 RegistrationsController 不再仅负责处理用户注册,还负责管理其他用户。

您几乎可以使用 Rails 脚手架 (rails g scaffold users --skip-migration --skip-model),因为它与 CRUD 处理任何其他资源并没有什么不同。您真正需要的只是:

# 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');
});