SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Enthusiast Stevenwulf's Avatar
    Join Date
    May 2002
    Location
    Berkeley
    Posts
    76
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Restricting the Deletion of Children

    Does anyone know if ActiveRecord has a way for you to specify that a Parent object can not be deleted if it has children?

    I know that you can specify that a parent should--by default--delete all its children. But I can't seem to find anything on restricting this behaviour

    Code:
    has_many :dependent => :delete_all
    Thanks

  2. #2
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe:

    Code:
    class Post < ActiveRecord::Base
      before_destroy :check_comments
    
      def check_comments
         self.comments.empty?
      end
    end
    If the before_destroy callback returns false, that is, if the associated-comments list is not empty, the object will not be destroyed (as far as I know ;-)).

  3. #3
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, it will.

    If a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last.
    From Rails api docs.

  4. #4
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Luke Redpath
    Yes, it will.
    If a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last.
    From Rails api docs.
    Which still reads to me that the check_comments callback will be checked before destroy is called, it will just be the LAST callback checked.

  5. #5
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, but maybe the actual DELETE FROM ... will be cancelled too.

  6. #6
    SitePoint Enthusiast Stevenwulf's Avatar
    Join Date
    May 2002
    Location
    Berkeley
    Posts
    76
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks guys. This works great. Just to clarify, if the callback returns false, the object will not be destroyed.

    Code:
       class Vendor < ActiveRecord::Base
       
         # relationships
         has_many :software
       
         before_destroy :dont_destroy_if_children
       
         def dont_destroy_if_children()
       	software.empty? ? true : false
         end
       	
       end
    The following test passes

    Code:
        def setup()
      	@vendor = Vendor.find(1)
        end
      
         def test_delete()
       	# If vendor has childen, do not delete
       	assert_equal(false, @vendor.destroy)
       	assert_equal(1, @vendor.software.size)
       	assert_nothing_raised(ActiveRecord::RecordNotFound) { Vendor.find(@vendor.id) }
       	# You can delete the vendor, after you have deleted its children
       	@vendor.software.clear
       	assert(@vendor.destroy)
       	assert_raise(ActiveRecord::RecordNotFound) { Vendor.find(@vendor.id) }
         end
    Code:
       rooster > ruby test/unit/vendor_test.rb
       Loaded suite test/unit/vendor_test
       Started
       ....
       Finished in 0.147694 seconds.
       
       4 tests, 17 assertions, 0 failures, 0 errors

  7. #7
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Sgarissta
    Which still reads to me that the check_comments callback will be checked before destroy is called, it will just be the LAST callback checked.
    It says all the later callbacks and the associated action (create/delete whatever).

    By the way, this:

    PHP Code:
    software.empty? ? true false 
    Can simply be:

    PHP Code:
    software.empty? 
    Which will return a boolean value anyway!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •