Record gets destroyed unexpectedly

We're not psychic. (but if I had to take a guess it would be that the
parameters your controller receives aren't the ones you thought you'd
get).

Fred

Frederick Cheung wrote:

Couldn't find [Record] with ID=X

[Record] is the name of my model.

I always check that the record actually exists in my database, before I
press the "delete" link.

What is wrong here? Any ideas?

We're not psychic.

I don't expect you to be, either.

But I have been running through all my other models to check if
something could cause the problem, but there's nothing.

(but if I had to take a guess it would be that the
parameters your controller receives aren't the ones you thought you'd
get).

Yes, that's what I thought too. But I've also checked if the record's id
matches the id in params[:id].

Actually I thought, this was a comon problem. I see it's not. Therefore
I'll give you some code snippets, that might give a hint.

def destroy
    # Finding the current user's root folder.
    @root = Folder.find(:first, :conditions => "folder_id is null and
user_id = "+current_user.id.to_s)

    # Finding the upload to get destroyed. Error at following line:
    @upload = Upload.find(params[:id])

    # Deleting the upload on the harddrive.
    File.delete @upload.public_filename

    # Destroys the upload.
    @upload.destroy

    # If the file has been deleted from the user's root folder.
    if @root.id == @upload.folder_id
      # ... redirect to the home page.
      url = {}
    else
      # ... else redirect to the folder's parent folder.
      url = {:controller => "folders", :action => "show", :id =>
@upload.folder_id}
    end
    flash[:notice] = "..."
    # Redirect goes here.
    redirect_to url
end

According to my oppinion, there should be nothing wrong here. But what
about the model?

  has_attachment :storage => :file_system, :path_prefix => table_name
  belongs_to :folder
  validates_uniqueness_of :filename, :scope => :folder_id
  validates_presence_of :filename
  belongs_to :user, :foreign_key => "user_id"
  attr_accessor :email

Nothing unusual, right? This is the folder model. Each folder contains
both folders and uploads:

  acts_as_tree :order => "name", :foreign_key => 'folder_id'
  belongs_to :parent, :foreign_key => 'folder_id', :class_name =>
'Folder'
  has_many :children, :foreign_key => 'folder_id', :class_name =>
'Folder', :dependent => :destroy
  has_many :uploads, :dependent => :destroy
  belongs_to :user
  validates_uniqueness_of :name, :scope => :folder_id

Could anything in these code snippets cause the problem?

What's in the form/link that submits to this action ?

Fred

Frederick Cheung wrote:

parameters your controller receives aren't the ones you thought

What's in the form/link that submits to this action ?

I link to the destroy action in this way:

  - unless folder.uploads.empty?
    - folder.uploads.each do |upload|
      %tr
        %td= link_to "Delete", { :controller => "uploads", :action =>
"destroy", :id => upload.id }, :confirm => "xxx"

Couldn't find [Record] with ID=X

[Record] is the name of my model.

What [Record] is Upload < ActiveRecord ? is X in ID=X contained in your
Uploads table?

  - unless folder.uploads.empty?
    - folder.uploads.each do |upload|
      %tr
        %td= link_to "Delete", { :controller => "uploads", :action =>
"destroy", :id => upload.id }, :confirm => "xxx"

%td= link_to "Delete", { :controller => "uploads", :action => "destroy",
:id => upload }, :confirm => "xxx"

You should ensure that upload variable in looping folder.uploads is not
formed as array.

Reinhart
http://teapoci.blogspot.com

Visit Indonesia 2008 wrote:

Couldn't find [Record] with ID=X

[Record] is the name of my model.

What [Record] is Upload < ActiveRecord ? is X in ID=X contained in your
Uploads table?

Let me explain. I refered to the "Upload" table/model as "[Record]"
because I thought it was irelevant.

So the actual error message was:

    Couldn't find Upload with ID=X

X is (of course) an integer.

And yes, I always doublecheck if the Upload appears in the uploads table
with the correct id BEFORE I press delete.

But the interesting part is, that when I see the error message, I check
my uploads table again and see that the Upload has disappeared!

So even though the error is reached before the actual destroy command,
the upload gets destroyed anyway.

Isn't that strange?

  - unless folder.uploads.empty?
    - folder.uploads.each do |upload|
      %tr
        %td= link_to "Delete", { :controller => "uploads", :action =>
"destroy", :id => upload.id }, :confirm => "xxx"

%td= link_to "Delete", { :controller => "uploads", :action => "destroy",
:id => upload }, :confirm => "xxx"

You should ensure that upload variable in looping folder.uploads is not
formed as array.

It's not. Each item in folder.uploads refers directly to an instance of
the Upload model:

    has_many :uploads, ...

And yes, I always doublecheck if the Upload appears in the uploads
table
with the correct id BEFORE I press delete.

But the interesting part is, that when I see the error message, I
check
my uploads table again and see that the Upload has disappeared!

So even though the error is reached before the actual destroy command,
the upload gets destroyed anyway.

Isn't that strange?

It's almost as if the action is being run twice. Anything in the logs
that corroborates that. Any weird stuff in the controllers (filters
etc...) that could be doing that ?

Fred

David Trasbo wrote:

But the interesting part is, that when I see the error message, I check
my uploads table again and see that the Upload has disappeared!

So even though the error is reached before the actual destroy command,
the upload gets destroyed anyway.

Well, earlier you said that your Folder model has:

  has_many :uploads, :dependent => :destroy

Are your uploads getting deleted due to a folder delete?

Are there any clues in your logs? Any SQL for the deletes which give a
hint as to when the record was removed?

Frederick Cheung wrote:

Isn't that strange?

It's almost as if the action is being run twice. Anything in the logs
that corroborates that. Any weird stuff in the controllers (filters
etc...) that could be doing that ?

You're right!

I haven't noticed before, but when looking at the development log, I see
that the destroy command actually runs twice with a delay of one second.

The first time it raises an exception because (of some reason) it's
unable to delete the upload on the harddrive and then redirects to the
same page and raises the error, because the upload was deleted in the
database, but not on the harddrive.

THE FIRST ATTEMPT:

Processing UploadsController#destroy (for 127.0.0.1 at 2008-05-01
13:22:37) [GET]
  Session ID:
BAh7CToMY3NyZl9pZCIlNzI1ZjdmNmJlOWI1MzNlOGY3YWYyYzczZGNlMzI2%0AYjA6DnJldHVybl90bzAiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZs%0AYXNoOjpGbGFzaEhhc2h7AAY6CkB1c2VkewA6CXVzZXJpDw%3D%3D--871d3d4fbf896ca102143481e3552ce200f9d391
  Parameters: {"action"=>"destroy", "id"=>"13", "controller"=>"uploads"}
  e[4;35;1mUser Columns (0.015000)e[0m e[0mSHOW FIELDS FROM
`users`e[0m
  e[4;36;1mUser Load (0.000000)e[0m e[0;1mSELECT * FROM `users` WHERE
(`users`.`id` = 10) LIMIT 1e[0m
  e[4;35;1mFolder Load (0.000000)e[0m e[0mSELECT * FROM `folders`
WHERE (folder_id is null and user_id = 10) LIMIT 1e[0m
  e[4;36;1mUpload Columns (0.000000)e[0m e[0;1mSHOW FIELDS FROM
`uploads`e[0m
  e[4;35;1mUpload Load (0.000000)e[0m e[0mSELECT * FROM `uploads`
WHERE (`uploads`.`id` = 13) e[0m
  e[4;36;1mSQL (0.000000)e[0m e[0;1mBEGINe[0m
  e[4;35;1mUpload Destroy (0.016000)e[0m e[0m DELETE FROM `uploads`
WHERE `id` = 13
e[0m
Exception destroying "C:/Documents and Settings/David/BitNami RubyStack
projects/upload_service/uploads/0000/0013/config.php": [Errno::ENOENT]

(irelevant error stuff)

Redirected to http://localhost:3000/uploads/destroy/13
Completed in 0.59400 (1 reqs/sec) | DB: 0.15600 (26%) | 302 Found
[http://localhost/uploads/destroy/13]

SECOND ATTEMPT:

Processing UploadsController#destroy (for 127.0.0.1 at 2008-05-01
13:22:38) [GET]
  Session ID:
BAh7CToMY3NyZl9pZCIlNzI1ZjdmNmJlOWI1MzNlOGY3YWYyYzczZGNlMzI2%0AYjAiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%0Ac2h7BjoLbm90aWNlIidGaWxlbiBibGV2IHNsZXR0ZXQgdWRlbiBwcm9ibGVt%0AZXIuBjoKQHVzZWR7BjsHVDoOcmV0dXJuX3RvMDoJdXNlcmkP--cd74482945ff45272c0a38f8db32df54e0523318
  Parameters: {"action"=>"destroy", "id"=>"13", "controller"=>"uploads"}
  e[4;36;1mUser Columns (0.015000)e[0m e[0;1mSHOW FIELDS FROM
`users`e[0m
  e[4;35;1mUser Load (0.000000)e[0m e[0mSELECT * FROM `users` WHERE
(`users`.`id` = 10) LIMIT 1e[0m
  e[4;36;1mFolder Load (0.000000)e[0m e[0;1mSELECT * FROM `folders`
WHERE (folder_id is null and user_id = 10) LIMIT 1e[0m
  e[4;35;1mUpload Columns (0.016000)e[0m e[0mSHOW FIELDS FROM
`uploads`e[0m
  e[4;36;1mUpload Load (0.000000)e[0m e[0;1mSELECT * FROM `uploads`
WHERE (`uploads`.`id` = 13) e[0m

ActiveRecord::RecordNotFound (Couldn't find Upload with ID=13):

(more error stuff)

No I just need to know why the file is not getting deleted on the hard
drive...

David Trasbo wrote:

No I just need to know why the file is not getting deleted on the hard
drive...

It is actually deleted, but the exception is raised anyway.

Anybody who knows what makes Errno::ENOENT raise an exception even
though the file is deleted successfully?

David Trasbo wrote:

Anybody who knows what makes Errno::ENOENT raise an exception even
though the file is deleted successfully?

It will help if you post the code of the method doing the deleting...

Mark Bush wrote:

David Trasbo wrote:

Anybody who knows what makes Errno::ENOENT raise an exception even
though the file is deleted successfully?

It will help if you post the code of the method doing the deleting...

I already did:

    # Deleting the upload on the harddrive.
    File.delete @upload.public_filename

Mark Bush wrote:

David Trasbo wrote:

Anybody who knows what makes Errno::ENOENT raise an exception even
though the file is deleted successfully?

It will help if you post the code of the method doing the deleting...

I already did:

   # Deleting the upload on the harddrive.
   File.delete @upload.public_filename

Looking at attachment_fu it looks like it will try and destroy the file too.
Fred

Frederick Cheung wrote:

   # Deleting the upload on the harddrive.
   File.delete @upload.public_filename

Looking at attachment_fu it looks like it will try and destroy the
file too.
Fred

Of course, that's right.

Thanks, everybody!

David Trasbo wrote:

   # Deleting the upload on the harddrive.
   File.delete @upload.public_filename

Looking at attachment_fu it looks like it will try and destroy the
file too.
Fred

Of course, that's right.

Thanks, everybody!

Yark, I also found out why the redirection took place.

The "url" variable should've been set to {:controller => "home"}. {}
Redirects to the same page.