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.