Agile Rails book: depot problem 2


#1

My second problem is:

Listing users, and deleting them doesn’t work.

If I try to list user, i just get this list:

User Delete
User Delete
User Delete
User Delete

I’m using this code in the login_controller:

def list_users
@all_users = User.find(:all)
end

def delete_user
@id = params[:id]
if id && user = User.find(id)
begin
User.destroy
flash[:notice] = “User #{user.name} deleted”
rescue
flash[:notice] = “Can’t delete that user”
end
end
redirect_to_index(:action => :list_users)
end

and the list_users view looks like this:

<% for users in @all_users -%>


<%= User.name %>
<%= link_to ‘Delete’, { :action => ‘delete_user’, :id => id },
:confirm => ‘Are you sure?’ %>

<% end -%>

trying to delete a user gives:

ActiveRecord::RecordNotFound in Login#delete_user
Couldn’t find User with ID=30034968

By the way, I got this errormessage by clicking:

Delete

The user ID’s seem to be messed up, and I don’t see what I did wrong…

Johan.


#2

Hi,

try

<% for user in @all_users -%>


<%= user.name %>
<%= link_to ‘Delete’, { :action => ‘delete_user’,
:id => user },
:confirm => ‘Are you sure?’ %>

<% end -%>

HTH, Beate


#3

Thank you, listing users is working now.
But I still get an error message if I try to delete one:

–> http://localhost:3001/login/delete_user/1

ActiveRecord::RecordNotFound in Login#delete_user
Couldn’t find User with ID=30085920

Apparantly, I should have used user.name instead of User.name…
Could you explain me why I shouldn’t use a capital U in User.name?

Thank you,

Johan.


#4

Your suggested code didn’t work.
I don’t get an error message anymore,
but I get a flash notice: actionlist_users.
And the user doesn’t get deleted.

However, I managed to fix my problem:

def delete_user
id = params[:id]
if id && user = User.find(id)
begin
user.destroy
flash[:notice] = “User #{user.name} deleted”
rescue
flash[:notice] = “Can’t delete that user”
end
end
redirect_to(:action => :list_users)
end

Again, I typed User.destroy instead of user.destroy.
But you can use User.find instead of user.find.
I still don’t really get it: when do you have to use capital characters
/ when not?

Beate, thank you for helping me with my 2 problems!

Johan


#5

2006/2/5, Johan Van M. removed_email_address@domain.invalid:

Again, I typed User.destroy instead of user.destroy.
But you can use User.find instead of user.find.
I still don’t really get it: when do you have to use capital characters
/ when not?

User.find(…) means the model, i.e. find all or the first (depending
on your find) User from the table. user.destroy means the user set in
“user = User.find(id)”, a special user.

But i can understand you, this was a little bit confusing to me in the
beginning, too.

Beate


#6

2006/2/5, Johan Van M. removed_email_address@domain.invalid:

Thank you, listing users is working now.
But I still get an error message if I try to delete one:

–> http://localhost:3001/login/delete_user/1

ActiveRecord::RecordNotFound in Login#delete_user
Couldn’t find User with ID=30085920

there is a typo in your controller. This does not work:
@id = params[:id]
if id && user = User.find(id)

Try this:
@id = params[:id]
if @id && user = User.find(@id)

Apparantly, I should have used user.name instead of User.name…
Could you explain me why I shouldn’t use a capital U in User.name?

You can’t use “User”, as this is not definded in the view:
<% for user in @all_users -%>
I myself visualize this like “For every single user in @users”, so
“user” is my variable.

Beate


#7

It helps a lot!
Everything is clear now.

So this code:

id = params[:id]
if id && user = User.find(id)
begin
user.destroy
flash[:notice] = “User #{user.name} deleted”

actually does this:

It creates an instance variable id, based on the specified parameters.
If this id was created, a user instance variable is created, based on a
User in the User class, with the specified id.
Then this user instance variable (thus the User with the id you
specified) is destroyed, and a flash message appears.

And by typing in User.destroy - if this method existed - ,you would do
something like deleting all users?

Thank you all for your help! I love the RoR community :slight_smile:

Johan.


#8

Lowercase “user” is an instance variable… you can use it if you’ve
created or retrieved
a User into it (though you could also retrieve any other object into it
or you could call
the variable “rumplestiltskin”… but that would be more confusing). The
uppercase “User”
is the actual class.

So, when you do User.destroy you are calling a “class method”, meaning
the method is not
tied to an instance (a “static” method in Java). This shouldn’t work
because “destroy” is
not a class method.

When you do user.destroy you are calling an “instance method”, meaning
the method is tied
to a specific instance of User… and it does the work declared in that
method to the
instance you call it on. This should delete the row in the db that
corresponds to the User
object held in variable “user”.

The destroy method makes sense as an instance method, because you’re
destroying a specific
instance. The find method, on the other hand, makes sense as a class
method because you
don’t have an instance to call find on until you call find!

Hope that helps.

b


#9

Johan Van M. wrote:

actually does this:

It creates an instance variable id, based on the specified parameters.
If this id was created, a user instance variable is created, based on a
User in the User class, with the specified id.
Then this user instance variable (thus the User with the id you
specified) is destroyed, and a flash message appears.

And by typing in User.destroy - if this method existed - ,you would do
something like deleting all users?

Well, if User.destroy existed, it might do something like that… but it
doesn’t. You’ve
got it though… use class methods (defined by doing “def
self.methodname…”) to do stuff
that doesn’t make sense to have attached to a single instance and use
instance methods to
do stuff that does.

b