简体   繁体   中英

Rails 5 - Devise + Petergate - Admin edit other user registration

I have found some related questions but they don't seem to work for my case, they are either for older versions or don't fit my approach.

I have set up a User model with devise and it has two related models, it has one Contact Detail and many Addresses. I also have Petergate to get the roles.

I want any user to edit their registration (I have added contact details and addresses at the app/views/devise/registrations/edit.html.erb form) and admin can edit all.

The button in the contact details show page is implemented like this:

<%= link_to 'Edit Profile', edit_user_registration_path(@contact_detail.user) if logged_in?(:admin) || current_user.id == @contact_detail.user_id %>

and the edit form is the following

h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, as: resource_name, url: user_registration_path(resource_name), html: { method: :put }) do |f| %>
...
...
  <div>
    <%= f.fields_for :contact_detail do |contact_detail|%>
      <%= render "contact_detail_fields", f: contact_detail %>
    <% end %>
  </div>

  <div>
    <%= f.fields_for :addresses do |address_form| %>
      <%= render "address_fields", f: address_form %>
    <% end %>
  </div>

  <div class="form-group">
    <%= f.submit "Update", class: "btn btn-primary" %>
  </div>

But when I click the button on a user's contact details page, I always redirect to the admins edit page (/users/edit.1) and not to the user's edit page.

How can edit I the correct user's registration path?

My routes.rb file has the following:

  resources :addresses
  resources :contact_details
  devise_for :users, controllers: {
    registrations: 'my_registrations'
  }

I haven't made a users controller override and my models don't contain anything relevant.

Thanks in advance!

An admin section where you can CRUD other users is not actually a feature of Devise.

The Devise RegistrationsController is built from the ground up to only work for the current user. The routes are actually singular and don't contain an id segment. You would have to override pretty much everything to get it working and in the process you're steamrolling the Single Responsibility Principle.

If you want to CRUD other users just create a seperate route and controller just like you would for any other resource. You can just run rails g scaffold_controller users to scaffold one.

devise_for :users, controllers: {
  registrations: 'my_registrations'
}
resources :users

If you want to share view code between registrations and your users controller don't try to recycle your app/views/devise/registrations/edit.html.erb view. Instead spit the view into partials that can be resused.

# app/views/users/_fields.html.erb
  <div>
    <%= f.fields_for :contact_detail do |contact_detail|%>
      <%= render "contact_detail_fields", f: contact_detail %>
    <% end %>
  </div>

  <div>
    <%= f.fields_for :addresses do |address_form| %>
      <%= render "address_fields", f: address_form %>
    <% end %>
  </div>
  # ...

# app/views/users/_form.html.erb
<%= form_for(user) do |f| >
  <%= render "users/fields", f: f %>
  <%= f.submit, class: "btn btn-primary" %>
<% end %>

# app/views/users/new/html.erb
<%= render "form", user: @user %>

# app/views/users/new/edit.erb
<%= render "form", user: @user %>

# app/views/devise/registrations/edit.html.erb
# This might be broken due to your earlier modifications so might want to  
# regenerate the views 
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, as: resource_name, method: :put do|f| %>
  <%= render "users/fields", f: f %>
  <div class="form-group">
    <%= f.submit "Update", class: "btn btn-primary" %>
  </div>
<% end %>

While you can explicitly render another view by passing a path in the controller:

class UsersController < ApplicationController
  def edit
    @user = User.find(params[:id])
    render 'devise/registrations/edit', 
      locals: { resource: @user, resource_name: :user }
  end
end

This really just pushes the complexity down into the view layer. Editing your own account and someone else account is not the same thing and the view will end up full of conditionals sooner or later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM