Resources delete method not working with Devise - ruby-on-rails

I am using devise gem for authentication. For the admin user I am trying to create a page where he will see the list of all users and will be able to delete them. Because devise does not provide action for delete I created a controller where I created destroy action.
controller:
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed."
redirect_to("/devise")
end
The view is simple, it just lists all users and posts a delete link next to them.
<% #users.each do |user| %>
<%= user.email %> <%= link_to 'Delete', :controller => :devise, :action => :destroy, :id => (user[:id]), method: :delete, data: { confirm: "Are you sure you want to delete this user permanently?" } %>
<% end %>
Up until this point it works - the page displays all users and the delete link too. However, when I try to delete random users it just opens them in new window instead of deleting them.
My routes are as follows:
Rails.application.routes.draw do
devise_for :admins
devise_for :users
resources :devise
resources :centres
resources :users
#match '/users/:id', :to => 'devise#show', :as => :user, :via => :get
match '/users/:id', :to => 'devise#destroy', :as => :destroy_user, :via => :delete
root 'welcome#index'
get '/index', to: 'welcome#index'
get '/about', to: 'welcome#about'
get '/help', to: 'welcome#help'
end
I need to make the delete function work. Thank you.

This is the solution for the question I posted:
controlled:
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed."
redirect_to("/users")
end
view:
<%= link_to "delete", user, method: :delete,
data: { confirm: "Are you sure you want to permanently delete this user?" } %>
route:
match '/users/:id', :to => 'users#destroy', :as => :destroy_user, :via => :delete

As far as i know, device doesn't handle destroy action. You should create a custom controller and provide a destroy action. In my case, i create a users_controller
users_controller:
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :ok }
end
end
html.erb:
<%= link_to 'Delete', user, method: :delete, data: { confirm: 'Are you sure?' } %>
routes.rb:
match '/users/:id', :to => 'users#destroy', :as => :destroy_user, :via => :delete

Related

ActionController::ParameterMissing in TagsController#create

I am attempting to trigger a destroy action from an index page for tags attached to multiple records. However, when the action is triggered I get the above error in the create action. The error does not occur when the create action is invoked. My code is as seen below.
Tag Controller
class TagsController < ApplicationController
before_action :require_user, only: [:edit, :update, :destroy]
before_action :set_search
def new
#tag = Tag.new
end
def create
tag = Tag.create(tag_params)
if tag.save
redirect_to tags_path
else
redirect_to sign_up_path
end
end
def destroy
#tag = Tag.find(params[:tag_id])
#tag.destroy
redirect_to tags_path
end
private
def tag_params
params.require(:tag).permit(:name)
end
end
Routes
Rails.application.routes.draw do
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
resources :recipes do
resources :ingredients, :steps
put :favorite, on: :member
end
resources :users
get 'recipes' => 'recipes#index'
get 'recipes/:id' => 'recipes#show'
get 'signup' => 'users#new'
get 'tags' => 'tags#index'
get 'new_tags' => 'tags#new'
post 'tags' => 'tags#create'
delete 'tags' => 'tags#destroy'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
root 'recipes#index'
end
Index
<%= link_to 'New Tag', new_tags_path(#tag) %>
<% Tag.find_each do |tag| %>
<%= tag.name %>
<%= link_to 'Delete Tag', #tag,
method: :destroy,
data: { confirm: 'Are you sure?' } %>
<% end %>
This route:
delete 'tags' => 'tags#destroy'
means "/tags" with no id parameter.
You have to tell the router that you want a part of the url used as the :tag_id
delete 'tags/:tag_id' => 'tags#destroy'
Anyway, I'd recommend you to stick with rails conventions and just use
resources :tags
and on the controller
#tag = Tag.find(params[:id])
I'm not sure why are you setting the routes manually, if you are new to Rails read this link: https://guides.rubyonrails.org/routing.html
You even have this lines
get 'recipes' => 'recipes#index'
get 'recipes/:id' => 'recipes#show'
which are unnecessary since resources :recipes already creates them.
The error stemmed from a combination of issues in the Link To statement in the view. The Link as it should be written is below...
<%= link_to 'Delete Tag', tag_path(tag),
method: :delete,
data: { confirm: 'Are you sure?' } %>

Rails Routing Help - Edit/Show have :id/:action, but delete has :action/:id

my routes.rb
root 'pages#home'
get 'about', to: 'pages#about'
resources :articles
match ':controller(/:action(/:id))', :via => [:get, :post]
my articles_controller.rb
def delete
#article = Article.find(params[:id])
end
def destroy
article = Article.find(params[:id])
article.destroy
flash[:notice] = "Article destroyed successfully."
redirect_to(:action => 'index')
end
my delete.html.rb
<h2>Delete Article</h2>
<div class="subjects delete">
<h2>Delete Subject</h2>
<%= form_for(:article, :url => {:action => 'destroy', :id => #article.id}) do |f| %>
<p>Are you sure you want to permanently delete this subject?</p>
<p><%= #article.title %></p>
<div class="form-buttons">
<%= submit_tag("Delete Article") %>
</div>
<% end %>
</div>
Now the problem is when i click edit article its redirecting to
http://localhost:3000/articles/7/edit
Show is redirecting to localhost:3000/articles/7
Where as delete is redirecting to localhost:3000/articles/delete/8
and when clicking delete button it says The action '8' could not be found for ArticlesController
Why i dont get redirected to localhost:3000/articles/8/delete
i changed routes.rb to
match ':controller(/:id(/:action))', :via => [:get, :post]
in this delete works but edit doesnt.
You'll be best using the resources directive for the routes:
#config/routes.rb
resources :articles #-> url.com/articles/:id/destroy
resources :pages, only: [], path: "" do
get :about, on: :collection #-> url.com/about
end
root 'pages#home'
The above will provide the correct routes.
Your problem is you're submitting a form to try and change the value. This will not work; you'll need:
#app/views/articles/show.html.erb
<%= button_to "Delete", article, method: :delete, data: { confirm: "Are you sure?" } %>
This will call your posts#destroy controller & fire your code (which seems okay).

undefined local variable for message when creating delete link

For my inbox I created a way to delete multiple messages from the inbox. Now I am trying to setup how to delete the message the current user is viewing. There should be a link at the bottom of the message that reads Delete. When user clicks the Delete link the message will be deleted and user would be redirected to their inbox.
When adding the code to the controller, I am now unable to even view the inbox message. I get a undefined local variable or method "message" error when trying to view message, with the page title of NameError in Messages#show.
Anyone know how I can fix this problem?
New code added to controller:
def destroy
#message = Message.find(params[:id])
#message.destroy
flash[:notice] = "Successfully deleted message."
redirect_to user_messages_path(#user, #messages)
end
Messages controller:
Class MessagesController < ApplicationController
before_filter :set_user
def show
#message = Message.find(params[:id])
#message.readingmessage if #message.recipient == current_user
end
def destroy
#message = Message.find(params[:id])
#message.destroy
flash[:notice] = "Successfully deleted message."
redirect_to user_messages_path(#user, #messages)
end
private
def set_user
#user = current_user
end
end
show.html:
<%= link_to "remove", message, :confirm => 'Are you sure?', :method => :delete %>
routes:
Dating::Application.routes.draw do
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
get 'logout' => 'sessions#destroy'
get 'edit' => 'users#edit'
get "/profile/:id" => "users#show"
get "profile/:id/settings" => 'users#edit'
match 'settings/:id' => 'users#settings'
resources :users
resources :sessions
resources :password_resets
resources :galleries
resources :photos
resources :searches
resources :users do
get 'settings', on: :member
end
root to: 'users#new'
root to: 'galleries#index'
resources :users do |user|
resources :messages do
collection do
post 'delete_multiple'
end
end
end
I think you need to use #message in your link_to like this:
<%= link_to "remove", #message, :confirm => 'Are you sure?', :method => :delete %>

Devise/ Delete user Error

I am creating a form for an admin to go in and list, edit and delete users. I have tried many different variations for deleting a user and nothing works. I am wondering if it is because I need to use devise_for :users and resources :users in my routes.rb. This is because I have uploads/attachments linked to users. But here is my link
<%= link_to 'Delete',user, :method => 'delete', :confirm => 'Are you sure?' %>
And my routes.rb
# devise_for :users
devise_for :users do
get "/users/sign_out" => "devise/sessions#destroy", :as => :destroy_user_session
end
resources :users do
resources :attachments
end
The error I am receiving is The action 'destroy' could not be found for UsersController.
But my users controller has
def destroy
#user = User.find(params[:id]).destroy
redirect_to admin_index, :flash => { :success => 'User was successfully deleted.' }
end
If you are not using ajax for the requests, the problem is taht you ar using a link_to
In order to send the :method => 'delete' you have to use a button, jus like this:
<%= button_to 'Delete', user, :method => 'delete', :confirm => 'Are you sure?' %>
Because destructive action must be performed with a form submission:
http://www.w3.org/2001/tag/doc/whenToUseGet.html#checklist

Ruby routes and custom action

I'm trying to incorporate Devise and Cancan into a web app. I want users with :role => "admin" to be able to delete users, and Devise's destroy action only allows users to delete themselves, so I've created a custom action for this purpose. (To override the plugin's controller file, I've copied the registrations controller over to app/controllers/registrations_controller.rb.)
Here is my custom action in my registrations_controller.rb:
def destroy_user_account
#user = User.find_by_id(params[:user])
#user.destroy
redirect_to profiles_path, :flash => { :success => "User deleted!" }
authorize! :destroy, User, :message => "You don't have authorisation to delete this user."
end
Here is how I'm trying to use it, in a link on the page where you view a user's profile. (I have things set up so that each user has_one profile; profiles are what you see at the front end. A profile is automatically created in the profiles table on user registration.)
<% if can? :update, #profile %>
| <%= link_to 'Edit Profile', edit_profile_path(#profile) %>
| <%= link_to 'Edit Settings', edit_settings_path %>
<% end %>
<% if can? :destroy, #profile.user %>
| <%= link_to "Delete User", destroy_user_account(#profile.user),
:class => "delete",
:confirm => "Are you sure?",
:title => "Delete #{#profile.user.name}"
%>
<% end %>
My tests are showing 2 failures that I can't resolve:
1) ProfilesController GET show when signed in as an admin should
have a link to edit the profile
Failure/Error: get :show, :id => #profile
ActionView::Template::Error:
undefined method destroy_user_account' for #<#<Class:0x105b474a8>:0x1057f32e8>
# ./app/views/profiles/show.html.erb:41:in_app_views_profiles_show_html_erb___917863454_2195331000_0'
# ./spec/controllers/profiles_controller_spec.rb:143
2) ProfilesController GET show when signed in as an admin should
have a link to delete the user's account (using the
destroy_user_account action in the registrations controller)
Failure/Error: get :show, :id => #profile
ActionView::Template::Error:
undefined method destroy_user_account' for #<#<Class:0x105b474a8>:0x105806d20>
# ./app/views/profiles/show.html.erb:41:in_app_views_profiles_show_html_erb___917863454_2195331000_0'
# ./spec/controllers/profiles_controller_spec.rb:148
Also, when I try it out in my browser, clicking on the "Delete user" link gets me the following error:
Routing Error
No route matches "/destroy-user-account/2"
Here are the routes that should cover this:
devise_for :users, #:path => '',
:skip => [ :confirmations, :passwords, :registrations ],
:controllers => { :registrations => "registrations" } do
# Routes for ACCOUNT REGISTRATIONS
get "join", :to => "registrations#new", :as => :new_user_registration
post "join", :to => "registrations#create", :as => :user_registration
get "settings/account", :to => "registrations#show", :as => :settings
get "settings/account/edit", :to => "registrations#edit", :as => :edit_settings
put "settings/account", :to => "registrations#update", :as => :update_settings
delete "close-my-account/:id", :to => "registrations#destroy", :as => :close_my_account
delete "destroy-user-account/:id", :to => "registrations#destroy_user_account", :as => :destroy_user_account
Can anyone help with what I'm doing wrong?
In the browser it isn't matching the route because you're sending a GET request but the route only matches a DELETE request. The test fails because the route gives the name destroy_user_account_path instead of destroy_user_account.
Try:
<%= link_to "Delete User", destroy_user_account_path(#profile.user),
:class => "delete",
:confirm => "Are you sure?",
:title => "Delete #{#profile.user.name}"
:method => :delete
%>

Resources