For has_one and has_many association, Rails has options to delete dependent objects when the object they depend on is deleted. This corresponds to a foreign key constraint of ON DELETE CASCADE in SQL. Say we have two tables, persons and addresses, where persons has a foreign key column that references addresses. Further assume that there''s 1 to 1 relationship between persons and addresses. When the address referenced by a person is deleted, obviously something has to be done to the person record. When the has_one :person association on the address is given the option :exclusively_dependent => true (or :dependent), AR automatically deletes the person record. Now, consider the other way around. When the person is deleted and our business logic mandates that there''s a 1 to 1 relationship between persons and addresses, then the related address has to be deleted, too. In contrast to the case above, this is not required by database integrity. Still, I''m wondering, is there a reason why this is or should not be supported in AR? Michael -- Michael Schuerig You can twist perceptions mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org Reality won''t budge http://www.schuerig.de/michael/ --Rush, Show Don''t Tell
On Mon, 2005-08-22 at 21:39 +0200, Michael Schuerig wrote:> For has_one and has_many association, Rails has options to delete > dependent objects when the object they depend on is deleted. This > corresponds to a foreign key constraint of ON DELETE CASCADE in SQL. > > Say we have two tables, persons and addresses, where persons has a > foreign key column that references addresses. Further assume that > there''s 1 to 1 relationship between persons and addresses. When the > address referenced by a person is deleted, obviously something has to > be done to the person record. When the has_one :person association on > the address is given the option :exclusively_dependent => true > (or :dependent), AR automatically deletes the person record. > > Now, consider the other way around. When the person is deleted and our > business logic mandates that there''s a 1 to 1 relationship between > persons and addresses, then the related address has to be deleted, too. > In contrast to the case above, this is not required by database > integrity. Still, I''m wondering, is there a reason why this is or > should not be supported in AR? > > Michael >Do you mean like this? http://dev.rubyonrails.com/ticket/2015 Or the other way around? -Robby -- /****************************************************** * Robby Russell, Owner.Developer.Geek * PLANET ARGON, Open Source Solutions & Web Hosting * Portland, Oregon | p: 503.351.4730 | f: 815.642.4068 * www.planetargon.com | www.robbyonrails.com *******************************************************/
On Monday 22 August 2005 21:59, Robby Russell wrote:> On Mon, 2005-08-22 at 21:39 +0200, Michael Schuerig wrote:[snip]> > Now, consider the other way around. When the person is deleted and > > our business logic mandates that there''s a 1 to 1 relationship > > between persons and addresses, then the related address has to be > > deleted, too. In contrast to the case above, this is not required > > by database integrity. Still, I''m wondering, is there a reason why > > this is or should not be supported in AR? > > > > Michael > > Do you mean like this? > > http://dev.rubyonrails.com/ticket/2015 > > Or the other way around?The other way around. To express a 1 to 1 relationship among Person and Address, I''d like to write class Person belongs_to :address, :exclusive => true end class Address has_one :person, :exclusively_dependent => true end Meaning that when either a person or an address is destroyed, the related object is destroyed, too. I agree with the usefulness of :dependent => :destroy/:nullify on has_many, too. Michael -- Michael Schuerig Life is just as deadly mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org As it looks http://www.schuerig.de/michael/ --Richard Thompson, Sibella
Jeremy Huffman
2005-Aug-23 00:06 UTC
Re: Re: Why no (exclusively_)dependent on belongs_to?
> The other way around. > > To express a 1 to 1 relationship among Person and Address, I''d like to > write > > class Person > belongs_to :address, :exclusive => true > end > > class Address > has_one :person, :exclusively_dependent => true > end > > Meaning that when either a person or an address is destroyed, the > related object is destroyed, too. > > I agree with the usefulness of :dependent => :destroy/:nullify on > has_many, too. > > Michael >Couple of thoughts here. First, I usually think of a Person as having an address. Maybe an address has occupants but then you are modelling something a little bit different, and in that case the address is not dependent upon the occupants (if you remove them, you still have the building). So I''d consider reversing the relationship. Second, if its a 1:1 are you sure the address isn''t really just a collection of attributes of Person? You can model this using an Address object that aggregates these fields and a composed_of statement in your Person - you''d only have one table. I think traditional normalization rules only have us creating new tables when the relationships between data elements are other than 1:1.
On Tuesday 23 August 2005 02:06, Jeremy Huffman wrote:> > The other way around. > > > > To express a 1 to 1 relationship among Person and Address, I''d like > > to write > > > > class Person > > belongs_to :address, :exclusive => true > > end > > > > class Address > > has_one :person, :exclusively_dependent => true > > end > > > > Meaning that when either a person or an address is destroyed, the > > related object is destroyed, too.> Couple of thoughts here. First, I usually think of a Person as having > an address. Maybe an address has occupants but then you are modelling > something a little bit different, and in that case the address is not > dependent upon the occupants (if you remove them, you still have the > building). So I''d consider reversing the relationship.I have to admit that I''m not sure here. I actually had the FK on either end of the association before. It''s a design problem, not implementation. Anyway -- I''d still like to have the :exclusive option on belongs_to.> Second, if its a 1:1 are you sure the address isn''t really just a > collection of attributes of Person?There are other objects that have 1:1 relationships to addresses, too. Michael -- Michael Schuerig The more it stays the same, mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org The less it changes! http://www.schuerig.de/michael/ --Spinal Tap, The Majesty of Rock
Jeremy Huffman
2005-Aug-23 01:46 UTC
Re: Re: Why no (exclusively_)dependent on belongs_to?
> > Couple of thoughts here. First, I usually think of a Person as having > > an address. Maybe an address has occupants but then you are modelling > > something a little bit different, and in that case the address is not > > dependent upon the occupants (if you remove them, you still have the > > building). So I''d consider reversing the relationship. > > I have to admit that I''m not sure here. I actually had the FK on either > end of the association before. It''s a design problem, not > implementation. Anyway -- I''d still like to have the :exclusive option > on belongs_to.Really my point is that I think you''ve got the relationship backwards and thats why its causing you conceptual problems. I don''t agree belongs_to should have an option to cascade deletes up to the parent. Frankly, this sounds bizarre. I am not aware of any RDBMS that offers a FK cascade backwards.
On Tuesday 23 August 2005 03:46, Jeremy Huffman wrote:> > > Couple of thoughts here. First, I usually think of a Person as > > > having an address. Maybe an address has occupants but then you > > > are modelling something a little bit different, and in that case > > > the address is not dependent upon the occupants (if you remove > > > them, you still have the building). So I''d consider reversing the > > > relationship. > > > > I have to admit that I''m not sure here. I actually had the FK on > > either end of the association before. It''s a design problem, not > > implementation. Anyway -- I''d still like to have the :exclusive > > option on belongs_to. > > Really my point is that I think you''ve got the relationship backwards > and thats why its causing you conceptual problems.When I turn it around, I run into the problem that there are multiple classes that have addresses. Person has an address and so does Company. It''s easy to have FK in the respective tables referencing the addresses table. In the other direction it''s not easy and I really don''t want to introduce polymorphism (STI) only to handle this.> I don''t agree belongs_to should have an option to cascade deletes up > to the parent. Frankly, this sounds bizarre. I am not aware of any > RDBMS that offers a FK cascade backwards.So the argument goes that implementers of RDBMS don''t have this feature on offer and they must have good reasons, but you don''t say what they are. Also, the name belongs_to carries far to many connotations; it should just have been called refers_to. Anyway, consider my case described above. To me it looks like cascade delete on belongs_to would come in handy. Michael -- Michael Schuerig Failures to use one''s frontal lobes mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org can result in the loss of them. http://www.schuerig.de/michael/ --William H. Calvin
Jeremy Huffman
2005-Aug-23 03:20 UTC
Re: Re: Why no (exclusively_)dependent on belongs_to?
> are. Also, the name belongs_to carries far to many connotations; it > should just have been called refers_to. Anyway, consider my case > described above. To me it looks like cascade delete on belongs_to would > come in handy.Well "belongs_to" is a very specific type of relationship, and it carries with it a set of implications. Those implications don''t really fit your use case, but that doesn''t mean "belongs_to" is wrong or that your use case is wrong. ActiveRecord doesn''t support every possible relationship. Perhaps it would be useful for it to also have a more generic "refers_to" that wouldn''t imply so much about the nature of the relationships, and that supported two-way dependencies.
Michael Schuerig wrote:>To express a 1 to 1 relationship among Person and Address, I''d like to >write > > class Person > belongs_to :address, :exclusive => true > end > > class Address > has_one :person, :exclusively_dependent => true > end > >Meaning that when either a person or an address is destroyed, the >related object is destroyed, too. > >Sorry, but this is wrong. What you want and need is, address_table -------------- id PK street etc... person_table ------------- id PK name etc.. person_residence_table ---------------------- address_id (FK on address_table.id) PK person_id (FK on person_table.id) PK If you need that address_table always has a person and vice-versa, make address_table.id (FK on person_residence_table.address_id) similarly for person_table You will just have to make sure that you FK are specified as deferrable until transaction is committed or you will not be able to insert new data :) Anyway, generally you can have an address without a person or a person without an address. Also 1-1 relationships do not exist since you generally have more than one person living at an address. Otherwise why the heck would you make an address table and a person table? Just stick them in one table and you have your 1-1 perfect relationship. Hope this helps, - Adam PS. Overall, exclusive 1-1 relationships between tables do not make sense in databases because that''s the entire purpose of tables in the first place!
On Tuesday 23 August 2005 05:36, Adam Majer wrote:> Anyway, generally you can have an address without a person or a > person without an address. Also 1-1 relationships do not exist since > you generally have more than one person living at an address. > Otherwise why the heck would you make an address table and a person > table? Just stick them in one table and you have your 1-1 perfect > relationship.Yes, generally. But that''s not what I''m trying to express. Also, as I noted previously, having the FK on Person, referring to Address, makes it easy to have have an FK on, say, Company referring to Address as well. With an FK in the other direction I''d have to deal with polymorphism in some way. A thing I''d like to avoid in the database if I can. Michael -- Michael Schuerig I am the sum total of the parts mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org I control directly. http://www.schuerig.de/michael/ --Daniel C. Dennett, Elbow Room
Peter Fitzgibbons
2005-Aug-23 18:28 UTC
RE: Re: Why no (exclusively_)dependent on belongs_to?
-----Original Message----- From: rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Michael Schuerig Sent: Tuesday, August 23, 2005 3:30 AM To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: [Rails] Re: Why no (exclusively_)dependent on belongs_to? On Tuesday 23 August 2005 05:36, Adam Majer wrote:> Anyway, generally you can have an address without a person or a person> without an address. Also 1-1 relationships do not exist since you > generally have more than one person living at an address. > Otherwise why the heck would you make an address table and a person > table? Just stick them in one table and you have your 1-1 perfect > relationship.Yes, generally. But that''s not what I''m trying to express. Also, as I noted previously, having the FK on Person, referring to Address, makes it easy to have have an FK on, say, Company referring to Address as well. With an FK in the other direction I''d have to deal with polymorphism in some way. A thing I''d like to avoid in the database if I can. Michael -- Michael Schuerig I am the sum total of the parts mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org I control directly. http://www.schuerig.de/michael/ --Daniel C. Dennett, Elbow Room _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails =======================================================================I''m seeing this as a desgin issue. Yes, you have Person -> Address and Company -> Address. Do you have all the overhead involved to "truly" normalize your address table ???? I''ve seen systems that did this correctly and it''s painful to maintain. Although, yes, the data is very pretty to look at. How many rows are you dealing with. The system I used dealt with 22 million Person/Companies and their associated Address... It made sense to have the overhead. Are you dealing with < 500,000 ?? Then the overhead to normalize to this level may not be necessary. Second, I''ve never experienced any code example that assumed the database was capable of automatically deleting the "other" side of a many-many table. This is ALWAYS done by some data-aware function (or stored procedure). Also, are you trying to say that your system, at some time, may say "Delete this address, it doesn''t exist anymore... Oh, and delete any Persons/Companies associated with it" ? This sounds weird because Person and Company are top-level entities in so many systems. Peter J. Fitzgibbons Applications Manager Lakewood Homes - "The American Dream Builder"(r) Peter.Fitzgibbons-STCS76aLmhk1y/cD6r8xzl6hYfS7NtTn@public.gmane.org (847) 884-8800
Jeremy Huffman
2005-Aug-24 00:27 UTC
Re: Re: Why no (exclusively_)dependent on belongs_to?
In many of my company''s (Fortune 100 Bank) applications, we abstract both person and company to "entity", "party" or some similar name. An entity is something we can do business with. It has some number of mailing addresses. It has a tax-id, etc, etc. If Michael modeled his domain this way, it might solve his problem but he might need STI which he has stated he does not want. I cannot say that the way we''ve modeled our business is right for Michael. Michael has said he doesn''t want to use STI to solve this. I think he has implied rails should make it easy to solve this without fully OOD, but lets be pragmatic. I can say that in a 1:*/has_many->belongs_to /parent->child relationship the parent is not dependent upon children. This is often explicit in the definition of such relationships, the definition of orphans, etc. I''d contend Michael wants more generic relationship support. I''d further contend that Michael will not be the only person to want such. This is where I wish I better understood the full philosophy of Rails. Does it want to steer us into some specific set of OO/relational patterns that solve some large percentage of all business problems - and thus steer people who "incorrectly" model their domain into this discussion list to debate and defend their application design, or does it wish to meet the wants/needs of as many people as possible within its niche? If someone submits a patch to support "refers_to" relationships with optional dependent support, would it be applied? Should this be integrated as the foundation of relationships? I''m anxious to see how long it takes to accept/reject my current patch of about 40 characters to make dependent optional for acts_as_tree, which is currently on by default. I''m not sure if I''m right that acts_as_tree should *not* always silently destroy children without a way (that I can think of) to intercept this in a before_destroy event (since the children are destroyed first, how can they know an attempt was made to destroy their parent which should be cancelled because we want children''s destruction to be explicit?). Likely there is some clever way in Ruby or Rails to solve my problem, or some better design but nevertheless I think that acts_as_tree should make dependency optional. On 8/23/05, Peter Fitzgibbons <Peter.Fitzgibbons-p2lxMnUesd41y/cD6r8xzl6hYfS7NtTn@public.gmane.org> wrote:> -----Original Message----- > From: rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Michael > Schuerig > Sent: Tuesday, August 23, 2005 3:30 AM > To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > Subject: [Rails] Re: Why no (exclusively_)dependent on belongs_to? > > On Tuesday 23 August 2005 05:36, Adam Majer wrote: > > Anyway, generally you can have an address without a person or a person > > > without an address. Also 1-1 relationships do not exist since you > > generally have more than one person living at an address. > > Otherwise why the heck would you make an address table and a person > > table? Just stick them in one table and you have your 1-1 perfect > > relationship. > > Yes, generally. But that''s not what I''m trying to express. Also, as I > noted previously, having the FK on Person, referring to Address, makes > it easy to have have an FK on, say, Company referring to Address as > well. With an FK in the other direction I''d have to deal with > polymorphism in some way. A thing I''d like to avoid in the database if I > can. > > Michael > > -- > > Michael Schuerig I am the sum total of the parts > mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org I control directly. > http://www.schuerig.de/michael/ --Daniel C. Dennett, Elbow Room > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > > =======================================================================> > I''m seeing this as a desgin issue. > Yes, you have Person -> Address and Company -> Address. Do you have all > the overhead involved to "truly" normalize your address table ???? I''ve > seen systems that did this correctly and it''s painful to maintain. > Although, yes, the data is very pretty to look at. > How many rows are you dealing with. The system I used dealt with 22 > million Person/Companies and their associated Address... It made sense > to have the overhead. Are you dealing with < 500,000 ?? Then the > overhead to normalize to this level may not be necessary. > > Second, I''ve never experienced any code example that assumed the > database was capable of automatically deleting the "other" side of a > many-many table. This is ALWAYS done by some data-aware function (or > stored procedure). > > Also, are you trying to say that your system, at some time, may say > "Delete this address, it doesn''t exist anymore... Oh, and delete any > Persons/Companies associated with it" ? This sounds weird because > Person and Company are top-level entities in so many systems. > > Peter J. Fitzgibbons > Applications Manager > Lakewood Homes - "The American Dream Builder"(r) > Peter.Fitzgibbons-STCS76aLmhk1y/cD6r8xzl6hYfS7NtTn@public.gmane.org > (847) 884-8800 > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
On Wednesday 24 August 2005 02:27, Jeremy Huffman wrote:> Michael has said he doesn''t want to use STI to solve this. I think he > has implied rails should make it easy to solve this without fully > OOD, but lets be pragmatic.Just for clarification: I''m not opposed to STI in principle. I haven''t used it so far (only vertical/horizontal inheritance with WebObjects years ago). My current impression is that STI would give me a considerable headache with NOT NULL and foreign key constraints. If I can, I''d like to avoid them. Michael -- Michael Schuerig Nothing is as brilliantly adaptive mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org as selective stupidity. http://www.schuerig.de/michael/ --A.O. Rorty, The Deceptive Self