Previously I was able to delete the user using an admin account, after I've added the recaptcha gem I was unable to do so.
I've tried the same method using recaptcha in adding a post and it works, but it doesn't work on delete.
users_controller.rb
def destroy
#user = User.find(params[:id])
if verify_recaptcha(model: #user) && #user.destroy
redirect_to #user
else
redirect_to posts_path
end
end
index.html.erb
<% #users.each do |user| %>
<td> <%= link_to "Delete", admin_destroy_user_path(user),
method: :delete, data: { confirm: "You sure?" },
:class => 'btn btn-danger' %>.
</td>
<% end %>
routes.rb
match 'users/:id' => 'users#destroy', :via => :delete, :as => :admin_destroy_user
Can you guys please help me to identify what seems to be the problem? Based on my understanding i think there's something wrong with the
if verify_recaptcha
because when i did something like !if verify_recaptcha && #user.destroy the user will be deleted and will show error message: reCAPTCHA verification failed, please try again. So i assume something is wrong with verifying the captcha
Related
I have created a user using devise gem. I have added a column admin to the User table which has boolean value. Now what I need is to add checkboxes after every user in users_page and give a feature so that when the checkbox is checked the value of admin column changes to true. How can I add the functionality?
users_controller.rb
class UsersController < ApplicationController
def users_page
#users = User.all
end
def change_user_role
#user = User.find(params[:id])
format.html { redirect_to users, notice: 'Role changed successfully' }
end
def destroy
#user = User.find(params[:id])
#user.destroy
if #user.destroy
redirect_to root_url, notice: "User deleted."
end
end
end
users_page.html.erb
<h1>Users</h1>
<% #users.each do |user| %>
<h5><%= user.email %></h5>
<%= user.admin %>
<%= form_tag({controller: "users", action: "change_user_role"}, method: "get") do %>
<%= check_box_tag(:admin, checked: false) %>
<p><%= submit_tag 'Submit Answer' %></p>
<% end %>
<br>
<%= link_to "Destroy", admin_destroy_user_path(user), method: :delete, data: { confirm: "You sure?" } %>
<% end %>
routes.rb
Rails.application.routes.draw do
root to: 'pages#home'
get 'users/users_page'
devise_for :users
match 'users/:id' => 'users#destroy', :via => :delete, :as => :admin_destroy_user
get 'users#change_user_role'
end
Here I should submit the value of the checkbox in users_page to change_user_role and update the value in db and redirect it to users_page. How can I do that?
First of all, change your get method to put in your routes.rb because you'll be updating the resource in database:
Rails.application.routes.draw do
root to: 'pages#home'
get 'users/users_page'
devise_for :users
match 'users/:id' => 'users#destroy', :via => :delete, :as => :admin_destroy_user
// it will require user id in your url
resources :users do
member do
put :change_user_role
end
end
end
More on routes here
Then change your view to something like this:
<h1>Users</h1>
<% #users.each do |user| %>
<h5><%= user.email %></h5>
<%= form_for(user, url: change_user_role_user_path(user)) do |f| %>
<%= f.check_box(:admin) %>
<p><%= f.submit 'Submit Answer' %></p>
<% end %>
<br>
<%= link_to "Destroy", admin_destroy_user_path(user), method: :delete, data: { confirm: "You sure?" } %>
<% end %>
More on forms here
Your controller should look something like this:
class UsersController < ApplicationController
def users_page
#users = User.all
end
def change_user_role
#user = User.find(params[:id])
// if user is updated successfully then redirect
if(#user.update_attributes(user_params)
format.html { redirect_to users, notice: 'Role changed successfully' }
end
end
def destroy
#user = User.find(params[:id])
if #user.destroy
redirect_to root_url, notice: "User deleted."
end
end
// new method added to allow specific attributes only and discarding other malicious attributes that user may send
def user_params
params.require(:user).permit(:admin)
end
end
More on parameters here
Hi I want to build an app using Ajax. Whenever a user visits an other user page he can add him as a friend by clicking add friend link. This is my current code in users/show page
<% if current_user.friend?(current_user,#user) %>
<%= link_to "Unfriend", relation_path(#relation), user: #user, method: :delete, data: { confirm: 'Are you sure? This action cannot be undone' }, class: 'btn btn-default' %>
<% elsif #user != current_user %>
<%= link_to "Add Friend", friendships_path(:friend_id => user), :method => :post, class: 'btn btn-default' %>
<% end %>
My code in relations controller
def create
if params[:friend_id]
if Relation.where(user_id: current_user.id, friend_id: params[:friend_id]).present?
redirect_to user_path(params[:friend_id]), notice: "Already friends"
elsif current_user.id == params[:friend_id]
redirect_to user_path(params[:friend_id]), alert: "Invalid Request"
else
#relation = current_user.relations.new(friend_id: params[:friend_id], subject: Constants::Subject::MAKE)
if #relation.save
friend = User.find(params[:friend_id])
friend.relations.create!(friend_id: current_user.id, subject: Constants::Subject::MAKE)
redirect_to user_path(params[:friend_id]), notice: "Added as friend"
else
redirect_to user_path(params[:friend_id]), alert: "Could not add as friend"
end
end
else
redirect_to current_user, notice: "Invalid Request"
end
end
I am following this Ryan Bates rails casts. How can I make the link_to add friend Ajax request instead of html request. The current code is working fine. I want to add Ajax functionality for this. I have seen a lot of questions but I could not understand what exactly to be done. Please help.
Add remote: true to the link_to tag. There is more information in the guides abou rails and ajax. You will need a respond_to block to handle the response.
Start with adding remote: true and use the console to see the call being made and what the response is. Then you can figure out how to handle the response.
<%= link_to "Add Friend", friendships_path(:friend_id => user), :method => :post, remote: true, class: 'btn btn-default' %>
Please take a look:
Move your buttons into a partial
Render it inside a div with ID = "actions"
Update your controller response with format js
Add field create.js.erb which render your buttons by javascript
Render your flashes box by javascript by the same way (if needed)
your view_file.erb
<div id="actions">
<%= render "views/realtions/actions", relation: #relation, friend: #user %>
</div>
views/realtions/_actions.html.erb
<% if current_user.friend?(current_user, friend) %>
<%= link_to "Unfriend", relation_path(relation), user: friend, method: :delete, remote: true, data: { confirm: 'Are you sure? This action cannot be undone' }, class: 'btn btn-default' %>
<% elsif friend != current_user %>
<%= link_to "Add Friend", friendships_path(friend_id: friend.id), method: :post, remote: true, class: 'btn btn-default' %>
<% end %>
views/realtions/create.js.erb
<%- if #friend.present? %>
$("#actions").html("<%= j render 'views/realtions/actions', relation: #relation, friend: #friend %>")
<%- end %>
// render your flashes to DOM here!
controllers/relations_controller.rb
def create
if params[:friend_id]
#friend = User.find(params[:friend_id])
if Relation.where(user_id: current_user.id, friend_id: #friend.id).present?
flash[:notice] = "Already friends"
elsif current_user.id == params[:friend_id]
flash[:error] = "Invalid Request"
else
#relation = current_user.relations.new(friend_id: params[:friend_id], subject: Constants::Subject::MAKE)
if #relation.save
#friend.relations.create!(friend_id: current_user.id, subject: Constants::Subject::MAKE)
flash[:notice] = "Added as friend"
else
flash[:error] = "Could not add as friend"
end
end
else
flash[:notice] = "Invalid Request"
end
respond_to do |format|
format.js
end
end
Hope this help
I'm trying to update a record in my Rails app using a button. I have a User and I want to update its school_id value. I have a School view page where a User can click on a button to add that school's id to the User school_id field. I'm struggling with the implementation. Here's what I have so far:
User controller:
def add_school
#user = User.find(params[:user_id])
#user.update_attributes(:school_id)
respond_to do |format|
flash[:notice] = "School has been added!"
format.html { redirect_to :back }
format.js
end
Button on School show page:
<%= button_to "Add School", add_school_user_path, :method => "put" %>
I tried to do this a different way by just adding code to the update action in the User controller but I couldn't get that to work either:
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:school_id])
flash[:notice] = "School has been added!"
redirect_to #user
end
if #user.update_attributes(params[:user])
flash[:notice] = "Successfully updated account and profile!"
end
end
What's the best way to pass the School's id into the User school_id column?
Thanks!!
EDIT 1: Routes
resources :users do
member do
get :following, :followers
put :add_school
end
Updated controller:
def add_school
#user = current_user
#school = School.find(params[:id])
#user.update_attributes(school_id: params[:school_id])
respond_to do |format|
flash[:notice] = "School has been added!"
redirect_to #user.school
end
end
Updated button link:
<%= button_to "Add School", add_school_user_path(#user, school_id: #school.id), :method => :put %>
Routing error:
No route matches {:action=>"add_school", :controller=>"users", :school_id=>1, :id=>nil}
You need a form for that instead of just abutton
<%= form_tag add_school_user_path(#user), method: put do -%>
<%= hidden_field_tag :school_id, #school.id -%>
<%= submit_tag 'Add school' -%>
<%- end -%>
you didn't provide the context code, maybe #user and #school are not the real variable names but you can get the idea from this
The provided answer is no longer entirely accurate. You can pass data and update a record with a button_to, so long as you aren't attempting to pass arbitrary data.
The button_to syntax would be something like this -- please note, this is my implementation of it, and it is not adjusted to your specific implementation as your controller would need additional adjustments from what you've specificed to accept certain params --:
<%= button_to "Mark Completed", todo_path(todo.id),
params: {:todo => { :id => todo.id, :completed => true, :user_id => current_user.id }},
method: :put, data: { confirm: "Mark this To-Do as being completed? This will hide it from view." } %>
You need to pass the whole hash into the call to .update_attributes.
Preferably, you will put school_id inside of user, so it will look like
# params[:user] = { school_id: 1 }
#user.update_attributes(params[:user])
Or you could code the school id manually
#user.update_attributes(school_id: params[:school_id])
Or, better yet, validate the association
#user.school = School.find(params[:school_id]
The path you would want is
user_add_school_path(#user, school_id: 1)
This is an old Q, but nevertheless for the sake of completeness. You do not necessarily need a form for a simple form-alike submission with a button/link. You can rely on jquery-ujs and data-params.
<%= link_to add_school_user_path(#user), class: "btn btn-xs btn-primary",
title: "Add school",
data: {remote: true, confirm: 'Are you sure?', method: 'put',
params: {user: {schoold_id: #school.id}}} do %>
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
Add school…
<% end %>
Note that you'd want to have school_params method in your controller akin to params.require(:user).permit(:school_id)
For my application, I have user accounts that people can sign up. I use the devise gem for the setup.
I also have a users page that lists out all the users registered to the site along with a destroy link. I want my administrator to be able to delete users and have it redirected to this users listing page. But when I click the link to destroy a specific user, it just redirects to the user profile page and does not delete the user from the database.
Does somebody know why?
**UPDATE: Updated code below as recommended and works now.
users_controller.rb
def destroy
#user = User.find(params[:id])
#user.destroy
if #user.destroy
redirect_to root_url, notice: "User deleted."
end
end
users/index.html.erb
<div class = "container">
<div id="usersview">
<b>USERS DIRECTORY</b>
<%= render #users %>
</div>
<center>
<%= will_paginate #users %>
</center>
</div>
users/_user.html.erb
<div class="comments">
<%= link_to user.name, user %>
<% if current_user.try(:admin?) && !current_user?(user) %>
<%= link_to "Destroy", admin_destroy_user_path(user), method: :delete, data: { confirm: "You sure?" } %>
<% end %>
</div>
routes.rb
devise_for :users
match 'users/:id' => 'users#destroy', :via => :delete, :as => :admin_destroy_user
match 'users/:id' => 'users#show', as: :user
resources :users
Devise doesn't provide this functionality out of the box. You have created your own destroy action, but you also have to create a custom route to that action.
In your routes:
match 'users/:id' => 'users#destroy', :via => :delete, :as => :admin_destroy_user
And then when creating the link:
<%= link_to "Destroy", admin_destroy_user_path(user), method: :delete, data: { confirm: "You sure?" } %>
According to devise 4.1 rake routes and views, using the following will help you delete the account once logged in as a user.
<%= link_to "Cancel my account", registration_path(current_user), data: { confirm: "Are you sure?" }, method: :delete %>
I think you have in your routes.rb: resources :users
The problem is that you are not passing the user that you want to delete when clicking:
users/_user.html.erb
<%= link_to "Destroy", user, method: :delete, data: { confirm: "You sure?" } %>
See that in second param I added user instead of user_url.
users_controller.rb
def destroy
#user = User.find(params[:id])
if #user.destroy
redirect_to root_url, notice: "User deleted."
end
end
In controller I removed an #user.destroy. You were calling it twice.
Hope it helps!
At least the latest version of Devise does provide such functionality out of the box, if a Devise-backed model has :registerable included.
class User < ApplicationRecord
devise :database_authenticatable, :registerable
end
Somewhere in app/views/layouts/application.html.erb:
<%= link_to 'Delete my account', user_registration_path, method: :delete if user_signed_in? %>
Or from rails c you can do something like this where "x" is user id.
user = User.where(id: x)
user.destroy(1)
I have a "manageUser" page, the route is like that:
map.manageUsers "manageUsers", :controller => "users", :action => "manageUsers"
and, it like a index of user, but provide a ban button for admin to ban the user, so, I have something like this:
<% #users.each do |user| %>
<td><%=h user.username %></td>
<td><%= link_to 'Ban !', user, :confirm => 'Are you sure?', :method => :ban %></td>
<%end%>
And the users controller have the method like this:
def ban
#user = User.find(params[:id])
#user.isBan = true
if #user.save
flash[:notice] = #user.username ' is successful banned.'
else
flash[:error] = #user.username ' may have greater power than you.'
end
redirect_to manageUsers_url
end
But when I click the link, it show me this address:
http://localhost:3000/users/46
With this error:
Unknown action
No action responded to 46. Actions:
What happen? thank you.
Because the :method in link_to helper is to define the HTTP method to request. But not the action in your controller.
You need use url_for system
<%= link_to 'Ban !', {:controller => 'users', :action => 'ban', :user_id => user.id}, {:confirm => 'Are you sure?'} %>