Hi All, I''m trying to prevent users from deleting a folder that has contents like this: class Folder < ActiveRecord::Base has_many :myfiles has_many :folders belongs_to :folder validates_uniqueness_of :name, :scope => "folder_id" before_destroy :dont_destroy_folder_with_contents def dont_destroy_folder_with_contents if Folder.find(id) != nil || Myfile.find(id) != nil raise "Cannot delete this folder because it has contents" end end end This works fine: the folder''s not deleted. However I do not get the neat error message with the red borders. I don''t seem to be able to figure out how to catch the exception and produce a neat error message. How do I get this working???? Thanks in advance! Grt, Mischa.
Hi, In your controller, you need to catch the exception, so: def destroy begin Folder.find(id).destroy rescue => e flash[:notice] = e end end Something like that.. 2005/10/24, Mischa Berger:> Hi All, > > I''m trying to prevent users from deleting a folder that has contents > like this: > > class Folder < ActiveRecord::Base > has_many :myfiles > has_many :folders > belongs_to :folder > validates_uniqueness_of :name, :scope => "folder_id" > > before_destroy :dont_destroy_folder_with_contents > def dont_destroy_folder_with_contents > if Folder.find(id) != nil || Myfile.find(id) != nil > raise "Cannot delete this folder because it has contents" > end > end > end > > This works fine: the folder''s not deleted. However I do not get the neat > error message with the red borders. I don''t seem to be able to figure > out how to catch the exception and produce a neat error message. How do > I get this working???? > > Thanks in advance! > > Grt, > Mischa. > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
> before_destroy :dont_destroy_folder_with_contents > def dont_destroy_folder_with_contents > if Folder.find(id) != nil || Myfile.find(id) != nil > raise "Cannot delete this folder because it has contents" > endWhat you want to be doing is running this code in the validate function, something like: def validate errors.add(:name_of_field_with_error, "cannot be deleted because it has contents") if (Folder.find(id) != nil || Myfile.find(id) != nil) end At least that''s if I understood you correctly! HTH Luke
>> Folder.find(id)This will throw an exception if id is not found, which might not be what you want/expect. You could however use: Folder.find_by_id(id) which will return nil if id is not found -----Original Message----- From: rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Luke Randall Sent: Monday, 24 October 2005 2:47 PM To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: Re: [Rails] Showing a neat error message> before_destroy :dont_destroy_folder_with_contents > def dont_destroy_folder_with_contents > if Folder.find(id) != nil || Myfile.find(id) != nil > raise "Cannot delete this folder because it has contents" > endWhat you want to be doing is running this code in the validate function, something like: def validate errors.add(:name_of_field_with_error, "cannot be deleted because it has contents") if (Folder.find(id) != nil || Myfile.find(id) != nil) end At least that''s if I understood you correctly! HTH Luke _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
> This will throw an exception if id is not found, which might not be what > you want/expect.Quite right. Thanks for picking this up! =)
> What you want to be doing is running this code in the validate > function, something like: > > def validate > errors.add(:name_of_field_with_error, "cannot be deleted because it > has contents") if (Folder.find(id) != nil || Myfile.find(id) != nil) > end > > At least that''s if I understood you correctly!From what I understood the validate function is only executed when you''re inserting or updating records, not when you are deleting.
> From what I understood the validate function is only executed when > you''re inserting or updating records, not when you are deleting.Hmm, once again my bad =) Sorry, should have paid closer attention to what you were trying to do. So what you are doing is right, having the code in before_delete. However, if you are looking for the validation style errors (with the red borders etc), you''d do something like this: def before_destroy if (Folder.find(id) != nil || Myfile.find(id) != nil) errors.add(:name_of_field_with_error, "cannot be deleted because it has contents") return false end end Be sure to change it to find_all (as above from Neville) if you don''t want to raise an exception if no folder is found (and most likely you don''t). I haven''t tried this, but I think it should work. Assuming you redirect_to an action which checks for errors for relevant model. Hopefully this time I''ve got it right =)
Thanks for your help! Yeah, Neville was right, that''s not what I wanted. This is what I meant to do: before_destroy :dont_destroy_folder_with_contents def dont_destroy_folder_with_contents if Folder.find(:all, :conditions => ["folder_id = ?", id]) != nil || Myfile.find(:all, :conditions => ["folder_id = ?", id]) != nil # raise "Cannot delete this folder because it has contents." errors.add_to_base("Cannot delete this folder because it has contents.") return false end end> I haven''t tried this, but I think it should work. Assuming you > redirect_to an action which checks for errors for relevant model. > Hopefully this time I''ve got it right =)I can''t figure out yet how to check for errors in the action I''m redirecting to. Do you have an example how to do this? I don''t seem to be able to access errors in the view or in the controller. Thanks again, Mischa.
An alternative which might be lighter/faster as it doesn''t instantiate an ActiveRecord instance: def before_destroy if (Folder.count("id = #{id}") > 0 || Myfile.count("id = #{id}") > 0) errors.add(:name_of_field_with_error, "cannot be deleted because it has contents") return false end end -----Original Message----- From: rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Luke Randall Sent: Tuesday, 25 October 2005 5:54 AM To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: Re: [Rails] Re: Showing a neat error message> From what I understood the validate function is only executed when > you''re inserting or updating records, not when you are deleting.Hmm, once again my bad =) Sorry, should have paid closer attention to what you were trying to do. So what you are doing is right, having the code in before_delete. However, if you are looking for the validation style errors (with the red borders etc), you''d do something like this: def before_destroy if (Folder.find(id) != nil || Myfile.find(id) != nil) errors.add(:name_of_field_with_error, "cannot be deleted because it has contents") return false end end Be sure to change it to find_all (as above from Neville) if you don''t want to raise an exception if no folder is found (and most likely you don''t). I haven''t tried this, but I think it should work. Assuming you redirect_to an action which checks for errors for relevant model. Hopefully this time I''ve got it right =) _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
> I can''t figure out yet how to check for errors in the action > I''m redirecting to. Do you have an example how to do this? I > don''t seem to be able to access errors in the view or in thecontroller. When you redirect, your rails app effectively gets a fresh new request from the browser for the new url. So your controller/request objects from the previous request are no longer available unless you put/retrieve them from somewhere like the flash, which is saved/restored across requests or in a cookie or your database
Take a look at: http://api.rubyonrails.com/classes/ActionController/Flash.html -----Original Message----- From: rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Neville Burnell Sent: Tuesday, 25 October 2005 10:26 AM To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: RE: [Rails] Re: Showing a neat error message> I can''t figure out yet how to check for errors in the action I''m > redirecting to. Do you have an example how to do this? I don''t seem to> be able to access errors in the view or in thecontroller. When you redirect, your rails app effectively gets a fresh new request from the browser for the new url. So your controller/request objects from the previous request are no longer available unless you put/retrieve them from somewhere like the flash, which is saved/restored across requests or in a cookie or your database _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
> Take a look at: > http://api.rubyonrails.com/classes/ActionController/Flash.htmlThanks again for your help! One more question. In the examples in the API they''re only storing strings in the Flash. Is it possible to store the entire errors object in the flash too? Thanks, Mischa.
> In the examples in the API they''re only storing strings in the Flash.Is it possible to store the entire errors object in the flash too? Yes, although there are some considerations: 1) the flash has to serializable, which should be the case for the objects you are storing 2) the class has to be available to ruby/rails when the session is reloaded on subsequent requests 3) large objects will have a resource cost to unload/load etc If you have the AWDWR book, take a look at section 16.6, pg 322-324. _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails