This question already has answers here:
Destroying users as an admin in Devise
(3 answers)
Closed 8 years ago.
I am trying to have an admin user delete other users. When i try to delete another users registration path it deletes the admin. Ive seen a few other posts with the same issue but have not been able to replicate it.
This is all_users.html.erb :
<h2 class="admin">All Users</h2>
<table class="table table-striped">
<tbody>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Cell Phone</th>
<th>Login Method</th>
<th>Delete User</th>
</tr>
</thead>
<tr>
<% #users.each do |user| %>
<td><%= user.first_name %></td>
<td><%= user.last_name %></td>
<td><%= user.cell_phone %></td>
<td><%= user.sprovider %></td>
<td><%= link_to user_registration_path, data: {confirm: "Are you sure?"}, method: :delete do%>
<span class="fa fa-trash-o"></span>
<% end %></td>
</tr>
<% end %>
</tbody>
</table>
Why is the current_user (the admin) being deleted instead of the user who i am calling the delete method on?
Looks like you're using Devise as the auth method for your users. Although devise will create routes for authentication / registration (and even a self account descruction) it does not create the regular REST controller for the User model.
I would suggest to create a new UsersController, with the regular index, show, delete, update, create, etc., as well as the regular route
resources :users
and use that controller for deleting other users. That way you could have a proper
<%= link_to #user, method: :delete, confirm: 'Are You Sure?' %>
Related
Can anyone tell me why the email addresses are not showing in the users list view below?
<p id="notice"><%= notice %></p>
<h1>Users</h1>
<table>
<thead>
<tr>
<th>Email</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #users.each do |user| %>
<tr>
**<td><%= user.email %></td>**
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New User', new_user_path %>
I'm not familiar with seeing the two asterisks around the element. I'm thinking that might be messing something up. If you want to bold the user's email you could try something like <td><b><%= user.email %></b></td>.
Are you getting any errors anywhere?
If the asterisks are just there to help us see the line of code, and you say that you see the users (and their emails) in the db, I think it could be one of two other relatively minor things.
Whats your controller look like for this view? Are you passing #users to this view? You could try just dumping #users on the page to make sure that it's available.
Is the field on your User model that holds the email called email?
I have been practicing working on this rails application where I want to allow registered users to put up profiles of their dogs. But I just can't get the My Dogs page to display dogs that belong only to the current logged in user.
I already have the dog and user models linked via Active Record (User has_many :dogs, Dog belongs_to :user) but I don't know what to type in my dogmenu view to display only dogs that belong to the current logged in user. This is what I have so far:
views\access\dogmenu.html.erb <-- Notice that the page that will display the dogs for the current logged in user is located in the view of another controller.
<div id="dogdisplay">
<table>
<tr>
<th>Dog Name</th>
<th>Breed</th>
</tr>
<% Dog.all.each do |d| %>
<tr>
<td><%= link_to d.dname, d %></td>
<td><%= d.breed %></td>
<td><%= link_to "Edit", edit_dog_path(d) %></td>
<td><%= link_to "Delete", d, method: :delete %></td>
</tr>
<% end %>
</table>
</div>
Thank you.
You will need two things to make this work:
A User object for the logged in user
Filter the dog list based on that id
1. Current User
This is pretty straightforward, you should be able to find this with a little googling. The big question is whether you've implemented your own user management, or you're using something like Devise to manage that.
If it's Devise, take a look at Rails Devise: get object of the currently logged in user?
If you wrote your own, you could take a look at how Devise or other user management gems provide access to the current user object. I'll leave that up to you because it seems beyond the scope of your question
2. Filter the dog list
This is pretty simple, you've got a few options:
From the view
current_user.dogs.each do |d|
Dog.where(user: current_user).each do |d|
Dog.where(user_id: current_user.id).each do |d|
From the controller
What #Sean Huber suggested is cleaner - use any of my methods above, but from the controller. E.g.
#dogs = current_user.dogs
In short, only take the dogs that have the user id matching the current user's.
I would suggest you set an instance variable in your controller action for the current user's dogs. Something like this:
def dogmenu
# this assumes you have a current_user already defined
#dogs = current_user.dogs
end
Then switch your view to use the instance variable #dogs:
<div id="dogdisplay">
<table>
<tr>
<th>Dog Name</th>
<th>Breed</th>
</tr>
<% #dogs.each do |d| %>
<tr>
<td><%= link_to d.dname, d %></td>
<td><%= d.breed %></td>
<td><%= link_to "Edit", edit_dog_path(d) %></td>
<td><%= link_to "Delete", d, method: :delete %></td>
</tr>
<% end %>
</table>
</div>
You need to retrieve the dogs related to the current user. Since these are the user's dogs, the logic should reside in the UsersController:
In _controller/users_controller.rb_
def your_method_name
#user = User.find(current_user.id)
#dogs = #user.dogs
render :dogmenu
end
Then in views/users/dogmenu.html.erb
<div id="dogdisplay">
<table>
<tr>
<th>Dog Name</th>
<th>Breed</th>
</tr>
<% #dogs.each do |d| %>
<tr>
<td><%= link_to d.dname, d %></td>
<td><%= d.breed %></td>
<td><%= link_to "Edit", edit_dog_path(d) %></td>
<td><%= link_to "Delete", d, method: :delete %></td>
</tr>
<% end %>
</table>
</div>
These are user dogs so the view really belongs in the users folder.
To get current user dogs, you can use object current_user
Change this
Controller
def dogmenu
#dogs = current_user.dogs
end
View
<% #dogs.each do |d| %>
To make current_user can execute in view put a helper method.
class ApplicationController < ActionController::Base
helper_method :current_user
def current_user
#current_user ||= User.find_by_id(session[:user])
end
end
Finally you can use current_user in your view or helper
<% current_user.dogs.each do |d| %>
<tr>
<td><%= link_to d.dname, d %></td>
<td><%= d.breed %></td>
<td><%= link_to "Edit", edit_dog_path(d) %></td>
<td><%= link_to "Delete", d, method: :delete %></td>
</tr>
<% end %>
It's good for trying the first one where you're using instance variable. Hopefully it can help.
I've been banging my head against this for a while. I know it's a simple problem, and I've reviewed other code examples where I'm doing this successfully, but, I'm completely stumped.
I'm getting an error "undefined method `page_leads' for nil:NilClass" when I try to go to the "Show" page. On my landing_pages "show" page I'm trying to show the leads that came in via that page.
My show page code for this is:
<table class="table table-striped">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Score</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #landingpage.page_leads.each do |page_lead| %>
<tr>
<td><%= page_lead.fname %></td>
<td><%= page_lead.lname %></td>
<td><%= page_lead.score %></td>
<td><%= link_to 'Show', page_lead %></td>
<td><%= link_to 'Edit', edit_page_lead_path(page_lead) %></td>
<td><%= link_to 'Destroy', page_lead, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
My landing_page model has:
has_many :page_leads
My page_lead model has:
belongs_to :landing_page
My controller code for the "show" method for both landing_pages and page_lead is:
def show
#landing_page = LandingPage.all(landing_page_params)
end
On my page_leads table I have the "landing_page_id" field so I can associate the landing page to the lead.
Any ideas what I'm doing wrong?
Thanks in advance
Your controller action does not load any instance of a model. You expect it to load an instance of a LandingPage (usually the one in params[:id] for a show action). So your controller should assign it:
# `GET /landing_pages/:id`
def show
#landingpage = LandingPage.find( params[:id] )
end
It is because your #landingpage instance variable is not defined when you run that code.
Basically, in your controller's action, you should have something like:
def show
#landinpage = ... # insert your definition here
# rest of your controller's action
end
I generated a scaffold for a To-Do List app, and I left out some columns to add later.
I ran the command to create a migration to add a new column named client and I changed my files so that it shows on the projects index and form, but when i enter something into the client field and submit, it doesn't save the information and remains blank..
Update 1:
Here is whats in my routes:
'
Rails.application.routes.draw do
root :to => 'projects#index'
resources :projects
end
'
Here is my index view:
'
<h1 id="title">Project List</h1>
<table>
<thead>
<tr id="headers">
<th>Title</th>
<th>Client</th>
<th>Description</th>
<th>Hours</th>
<th>Done</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody class="col-md-2" id="listItems">
<% #projects.each do |project| %>
<tr id="table">
<td><%= project.title %></td>
<td><%= project.client %></td>
<td><%= project.description %></td>
<td><%= project.hours %></td>
<td><%= project.done %></td>
<td><%= link_to " #{image_tag('show.png')}".html_safe, project, id:'showButton' %></td>
<td><%= link_to " #{image_tag('edit.png')}".html_safe, edit_project_path(project), id:'editButton' %></td>
<td><%= link_to " #{image_tag('destroy.png')}".html_safe, project, id:'destroyButton', method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Project', new_project_path, id:"new" %>
<footer id="footer">Copyright 2014 Kira Banks</footer>
'
To keep your application secured, Rails has a feature called Strong Parameters and the docs says:
It provides an interface for protecting attributes from end-user
assignment. This makes Action Controller parameters forbidden to be
used in Active Model mass assignment until they have been whitelisted.
So, basically you need to whitelist the new client attribute in the Projects controller by adding it to the list:
class ProjectsController < ApplicationController
# ...
# at the end of the file
private
def project_params
params.require(:project).permit(:title, :description, :hours, :done, :client)
end
end
How can I return data from the database on another page?
I can file this under: views / posts / index.htm.erb
<h1>Listing posts</h1>
<table>
<tr>
<th>Titulo</th>
<th>Conteudo</th>
<th>Categoria</th>
<th>Criado em</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #posts.each do |post| %>
<tr>
<td><%= post.titulo %></td>
<td><%= post.conteudo %></td>
<td><%= post.category.name %></td>
<td><%= post.created_at.strftime("%d/%m/%Y") %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Delete', post, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Post', new_post_path %>
And I wanted to display these values on another page: views / home / blog.html.erb
How do I do this? Could you explain all the steps so that I can display these values in my other page.
Thanks Kocur4d
but how do I get only some information? eg: I would like that to appear in the title of the post page like this way (in blog.html.erb):
<div class="post-title">
<h2 class="title"> <a href="link_to_post"> **<% = post.titulo%>** </ a> </ h2>
</ div>
Step 1. Create controller
In your app root directory run:
rails g controller home blog
Modify controllers/homes_controller.rb :
class HomesController < ApplicationController
def blog
#posts = Post.all
end
end
Your controllers/posts_controller.rb should be already set up. Minimum what you need for your question is to have index method defined you might have other methods as well:
class PostsController < ApplicationController
def index
#posts = Post.all
end
end
Step 2. Extract Partial
change views/posts/index.htm.erb :
<h1>Listing posts</h1>
<%= render partial: 'shared/posts', object: #posts %>
<%= link_to 'New Post', new_post_path %>
create/modify views/home/blog.html.erb :
<h1>Listing posts</h1>
<%= render partial: 'shared/posts', object: #posts %>
<%= link_to 'New Post', new_post_path %>
create views/shared/_posts.html.erb :
<table>
<tr>
<th>Titulo</th>
<th>Conteudo</th>
<th>Categoria</th>
<th>Criado em</th>
<th></th>
<th></th>
<th></th>
</tr>
<% posts.each do |post| %>
<tr>
<td><%= post.titulo %></td>
<td><%= post.conteudo %></td>
<td><%= post.category.name %></td>
<td><%= post.created_at.strftime("%d/%m/%Y") %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Delete', post, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
Step 3. Set up routes.
You should have something like this in your routes.rb file:
resources :posts or match 'posts/index' => 'posts#index'
add this to config/routes.rb:
match 'home/blog' => 'home#blog'
so it might look like this(there is few variants):
config/routes.rb:
YourAppName::Application.routes.draw do
root to: 'posts#index'
resources :posts
match 'home/blog' => 'home#blog'
end
Now when you start rails server(assuming standard configuration) and visit:
127.0.0.1:3000/posts/index and 127.0.0.1:3000/home/blog
you should see same content.
This should work copy-and-paste but I could make some typos and other small mistakes(hope not, if ill find any ill try to edit them asap). In general look at it as you need 3 steps to forward http request down your rails application stack.
Map url to controllers using routes.
Create controllers and inside prepare data for views.
Display data in Views.
Look around in Rails Guides, Rails for Zombies and Rails Tutorial for more info.
---------Upadate to your second question-----------
I don't really understand what would you like to achieve?? At the moment both index.html.erb and blog.html.erb showing the same data, that was what you ware asking for?
post representing one post and is available in sharde/_posts.html.erb. You can't reference it from index.html.erb or blog.html.erb.
#posts represents all the posts and its available in index.html.erb or blog.html.erb.
render partial: 'shared/posts', object: #posts -- this line say "Hey man! Paste here content of shared/posts file, and btw I have here a local variable #posts so if you need to use that date in shared/posts file Ill name it posts from in side there"
To make them look different modify both files and part that will be identical for both of them is in a sharde/_posts.html.erb.
Try for example remove this line:
<td><%= post.category.name %></td>
from shared file to see what is going to happen.
Add some html tags and thinker with it.
Rails has may helper methods available' to find out about them check the links I give you and google, google, google.
Try to add some links with link_to helper
In your home controller, for the blog method, set #posts as you need...
Maybe
#posts = Post.all