On 11.3.2005, at 10:03, Adelle Hartley wrote:> > # account is dependent, therefore is destroyed when reference to > owner > is lostThis comment indicates that the relationship is specified as dependent. In that case I would certainly expect the orphaned row to be deleted, too, i.e. (ii). Otherwise there wouldn''t be any use for "dependent => true". Of course the code needs to be prepared for situations where the user has used referential integrity constraints in his db, so that it won''t bomb even if the dependent row was deleted already by the db.> (ii) ActiveRecord should delete the unused record from the Accounts > table > and Account.find(old_account_id) should raise an exception (which is > what > the test currently expects but doesn''t get). > > Personally, I prefer to let the RDBMS take care of these kinds of > issues > (ie, I prefer the first option). Even if I didn''t prefer it that way, > a > legacy database might have referential integrity rules setup such that > ActiveRecord would be duplicating effort in this instance.Yes, but there are databases (may I name MySQL) that don''t support referential integrity, so taking away that functionality from Rails would be a big disadvantage for users of them. You can always leave the dependency declaration away from your model definition if you just want to depend on your database in these issues. Cheers, //jarkko -- Jarkko Laine http://jlaine.net http://odesign.fi _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Hi all, I''ve been working on cleaning up the unit tests for ActiveRecord. Here''s one of the errors/failures that I get when I run the tests for MySql: 1) Failure: test_natural_assignment_to_nil(HasOneAssociationsTest) [./test/associations_test.rb:98]: <ActiveRecord::RecordNotFound> exception expected but none was thrown. The source for this test is a follows: def test_natural_assignment_to_nil old_account_id = @signals37.account.id @signals37.account = nil @signals37.save assert_nil @signals37.account # account is dependent, therefore is destroyed when reference to owner is lost assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) } end What exactly is the desired behaviour here? I would expect that either: (i) We end up with an orphaned record in the Accounts table and Account.find(old_account_id) shouldn''t raise an exception (which is what is currently happening) OR (ii) ActiveRecord should delete the unused record from the Accounts table and Account.find(old_account_id) should raise an exception (which is what the test currently expects but doesn''t get). Personally, I prefer to let the RDBMS take care of these kinds of issues (ie, I prefer the first option). Even if I didn''t prefer it that way, a legacy database might have referential integrity rules setup such that ActiveRecord would be duplicating effort in this instance. What do other people here think? I haven''t been using ActiveRecord long enough to know whether this area had already been addressed. Adelle.
Jarkko Laine wrote:> Yes, but there are databases (may I name MySQL) that don''t > support referential integrity, so taking away that > functionality from Rails would be a big disadvantage for > users of them. You can always leave the dependency > declaration away from your model definition if you just want > to depend on your database in these issues.Thanks. I hadn''t spotted the "dependent => true". I am pretty close to crying "uncle" on the subject of how this is supposed to be implemented.>From ActiveRecord/base.rb:def association_accessor_methods(association_name, association_class_name, association_class_primary_key_name, options, association_proxy_class) ..... ..... define_method("#{association_name}=") do |new_value| association = instance_variable_get("@#{association_name}") if association.nil? association = association_proxy_class.new(self, association_name, association_class_name, association_class_primary_key_name, options) end association.replace(new_value) unless new_value.nil? instance_variable_set("@#{association_name}", association) else # this is where "test_natural_assignment_to_nil" ultimately sends us. instance_variable_set("@#{association_name}", nil) return nil end association end end I''ve commented the line where we ultimately end up during "test_natural_assignment_to_nil". I''m still getting the hang of the "Ruby/ActiveRecord Way", so is this where the record should be deleted, or is there a more appropriate mechanism (such as modifying the definition of "instance_variable_set")? Adelle.