Forum: Ruby on Rails database changes aren't happening in callback before_destroy()

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Vikrant (Guest)
on 2009-01-16 17:03
(Received via mailing list)
I have a model Model1 with the before_destory() method defined as
below.

def before_destroy
 self.status = 'deleted'
 self.save!
 return false #don't want to delete the row.
end

But in the database the change in the status column doesn't get
changed to 'deleted'

I then tried this

def before_destory
 self.status = 'deleted'
 self.save!
 n = Model1.find self.id    #Set the breakpoint here in NetBeans IDE.
 return false
end

I then checked the value of n.status and it was 'deleted', but in the
database it was still 'active' (the other value).

I also tried this

Controller1 < ApplicationController
 def action1
  m = Model1.find params[:id]
  m.destroy
  n = Model1.find m.id #Set the breakpoint here
 end
end

Even here the value of n.status was 'deleted', but in the database it
was the previous value. (Showed this example just to show that even in
controller I'm getting the same).

After a bit of of looking through Rails API, I found out that model
callbacks like before_destroy are transactional. so they get rolled
back if any error raised. So I tried this.

def before_destroy
 self.status = 'deleted'
 self.save!
 raise self.errors.inspect
 return false
end

The above code made sure that there are no errors attached, so
self.save! should run fine (or at least it should raise error!).
So I don't know now, why my changes are not being written to the
database. Is it because I'm returning false from the before_destroy()
method? If yes, then how can I save the changes made in before_destroy
() callback and also the row doesn't get deleted?

I'm using SQLite and I've also noticed that a 'development-journal'
file get created, while I've paused the code somewhere in between the
before_destroy() method. (That may be the transaction thing, I guess.)

I'm using -
Rails 2.2.2
SQLite 3.5.9
Ubuntu 8.10 (Intrepid) x64
Frederick C. (Guest)
on 2009-01-16 17:33
(Received via mailing list)
On 16 Jan 2009, at 15:02, Vikrant wrote:

> But in the database the change in the status column doesn't get
> changed to 'deleted'
>
> I then tried this
>
> def before_destory
> self.status = 'deleted'
> self.save!
> n = Model1.find self.id    #Set the breakpoint here in NetBeans IDE.
> return false
> end

Have you tried looking at development log to see exactly what queries
run  ?

Fred
Vikrant (Guest)
on 2009-01-16 17:43
(Received via mailing list)
Yes, just what it should be - UPDATE "model1" SET "updated_at"
= .........., "status" = "deleted" WHERE id = 40
but still the database isn't reflecting that. Also I can not find any
transaction rollback specific information in the log, as this is the
last query to the database for that HTTP request.

On Jan 16, 8:32 pm, Frederick C. <removed_email_address@domain.invalid>
Ilan B. (Guest)
on 2009-01-16 17:53
Vikrant wrote:
> I have a model Model1 with the before_destory() method defined as
> below.
>
> def before_destroy
>  self.status = 'deleted'
>  self.save!
>  return false #don't want to delete the row.
> end
>

Your transaction isn't completed until the request is completed.  If you
check your DB, you will not see any changes until the request has been
completed (assuming that your transaction level is beyond dirty reads)

Secondly, you shouldn't save in a before_destroy filter

I also believe that returning false will abort the transaction and you
will be left with an unmodified data source.

ilan
Vikrant (Guest)
on 2009-01-16 18:13
(Received via mailing list)
Well, I can't find the problem, but I guess I have an alternative
solution, and that is to use a new method named Model1.make_deleted()
which does the deletion work. Also, then I should stop destory() from
being executed (by raising some kind of exception in before_destroy()
method).
I guess that shall do the work, but I'm still thinking if there is a
standard way of marking a row as deleted, while not actually deleting
the row, since the above solution doesn't seem to be in compliance
with Rails-way. (Callbacks are made for some purpose after all).


On Jan 16, 8:53 pm, Ilan B. <removed_email_address@domain.invalid>
This topic is locked and can not be replied to.