Forum: Ruby on Rails don't destroy last user

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.
9acb6dd7bd59496bd005c4434a3dd475?d=identicon&s=25 Alexander (Guest)
on 2006-02-18 18:30
How would I stop the last user being deleted.
The following code doesn't work.


before_destroy :dont_destroy_last_user

# Don't delete user if it the last one
def dont_destroy_last_User
    raise "Can't destroy last user" if User.length < 1
end
A2b2f4ee23989dc68529baef9cbddcd6?d=identicon&s=25 Julian 'Julik' Tarkhanov (Guest)
on 2006-02-18 18:44
(Received via mailing list)
On 18-feb-2006, at 18:30, Alexander wrote:

> How would I stop the last user being deleted.
> The following code doesn't work.

before_destroy :check_if_last_user

private
   def check_if_last_user
     raise "Last user can't be deleted" if self.class.count == 1
   end
6dab365a82517fb694650a57ee88e4a4?d=identicon&s=25 joey__ (Guest)
on 2006-02-18 18:44
Alexander wrote:
> How would I stop the last user being deleted.
> The following code doesn't work.
>
>
> before_destroy :dont_destroy_last_user
>
> # Don't delete user if it the last one
> def dont_destroy_last_User
>     raise "Can't destroy last user" if User.length < 1
> end
Change to:
> # Don't delete user if it the last one
> def dont_destroy_last_User
>     raise "Can't destroy last user" if User.count == 1
> end

Untested,but should work

joey__
9acb6dd7bd59496bd005c4434a3dd475?d=identicon&s=25 Alexander (Guest)
on 2006-02-18 19:06
Julian 'Julik' Tarkhanov wrote:
> On 18-feb-2006, at 18:30, Alexander wrote:
>
>> How would I stop the last user being deleted.
>> The following code doesn't work.
>
> before_destroy :check_if_last_user
>
> private
>    def check_if_last_user
>      raise "Last user can't be deleted" if self.class.count == 1
>    end

Thanks

Also 'raise' creates quite a ugly error message. Is there any way of
redirecting and using flash instead?

Alex
A2b2f4ee23989dc68529baef9cbddcd6?d=identicon&s=25 Julian 'Julik' Tarkhanov (Guest)
on 2006-02-18 19:14
(Received via mailing list)
On 18-feb-2006, at 19:06, Alexander wrote:

>>      raise "Last user can't be deleted" if self.class.count == 1
>>    end
>
> Thanks
>
> Also 'raise' creates quite a ugly error message. Is there any way of
> redirecting and using flash instead?


I think the neat way would be with an exception catcher

in the model:

class LastUserCantBeDeleted < RuntimeError; end;

.... raise LastUserCantBeDeleted if self.class.count == 1


in the controller

begin
   @user.destroy!
rescue LastUserCantBeDeleted
   flash[:error] = "This is the last one'
   redirect_to :referer # or something like that
end

A less neat way would be to return false from the method and thus
stop the callback chain, and then


unless @user.destroy!
   flash[:error] = "This is the last one"
   # ... etc
end
15619be638a3ae3d6f86a4995c6484c1?d=identicon&s=25 Dee Zsombor (Guest)
on 2006-02-19 12:03
(Received via mailing list)
Julian 'Julik' Tarkhanov wrote:
>   flash[:error] = "This is the last one'
> end
This will not work if you have two independent FCGI/SCGI processes
trying
to delete the last user at the same time. Might sound bit extreme, but
its
quite possible for example if the user clicks rapidly the submit button
twice.

You'll need to wrap the deletion and the counting of users in a
transaction. The first beta release of AWDWR had similar code for
preventing the deletion of the last administrator. Revised version was
simpler not allowing to delete 'Dave' user. That's another alternative.
This topic is locked and can not be replied to.