I''ve tried tackling this many ways on my own and can''t find a good solution: Breaking it down to something simplier... Venue has one address Person has one address Address belongs to state Assuming I don''t want to do tables for venue_addresses and person_addresses. What is the best way to model this using rails... big thing here is i want to be able to reuse a partial for creating/modeling an address. I tried doing it where... ugly as it is... venue and person have the address id so it becomes a belongs_to but that is really a lie and a hack and leads to code like... @venue = Venue.new(@params[:venue]) @venue.address = Address.new(@params[:address]) Can someone give me an idea of the best way to deal with something like this? _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Sean T Allen wrote:> I''ve tried tackling this many ways on my own and can''t find a good > solution: > > Breaking it down to something simplier... > > Venue > has one address > > Person > has one address > > Address > belongs to stateI think this is more of an inheritance problem. More of an Address is a Venue or Address is a Person. Then you can create a models like that, one derived from another. You can also do this in PostgreSQL database - have one table inherited from another. I don''t know how to do this and maintain integrity in MySQL database unless you want complex foreign keys in the database. Ugly.. Anyway, has_one is suppose to be a 1-1 relationship so, A has_one :address Address belongs_to :a Anything else will not work very well with has_one, belongs_to. - Adam
Adam M. wrote:>Sean T Allen wrote: > > > >>I''ve tried tackling this many ways on my own and can''t find a good >>solution: >> >>Breaking it down to something simplier... >> >>Venue >>has one address >> >>Person >>has one address >> >>Address >>belongs to state >> >> > > >I think this is more of an inheritance problem. More of an Address is a >Venue or Address is a Person. Then you can create a models like that, >one derived from another. You can also do this in PostgreSQL database - >have one table inherited from another. I don''t know how to do this and >maintain integrity in MySQL database unless you want complex foreign >keys in the database. Ugly.. > >Anyway, has_one is suppose to be a 1-1 relationship so, > >A > has_one :address > >Address > belongs_to :a > >Anything else will not work very well with has_one, belongs_to. > >Don''t think I totally follow this... can you give a quick snippet of code for say A and as well a class that derives from it... I tried playing around with something like that but couldn''t get it to work at all... _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
On 5/13/05, Sean T Allen <sean-5W9FBhQXBOtBDgjK7y7TUQ@public.gmane.org> wrote:> I''ve tried tackling this many ways on my own and can''t find a good solution: > > Breaking it down to something simplier... > > Venue > has one address > > Person > has one address > > Address > belongs to state > > Assuming I don''t want to do tables for venue_addresses and person_addresses.This would only be necessary if you had M:N relationships of venues or people to addresses. You say they have but one, so ignore the idea of using join tables.> What is the best way to model this using rails... big thing here is i > want to be able > to reuse a partial for creating/modeling an address. > > I tried doing it where... ugly as it is... venue and person have the > address id > so it becomes a belongs_to but that is really a lie and a hack and leads > to code like... > > @venue = Venue.new(@params[:venue]) > @venue.address = Address.new(@params[:address]) > > Can someone give me an idea of the best way to deal with something like > this?belongs_to seems like the appropriate thing to use in this case. Perhaps you can explain why you think the above example is "ugly"? It seems quite natural to me. Ignore the implication of what the words "belongs_to" might mean or imply to you, because to ActiveRecord it is simply a way of defining a relation between two objects. Jason
Sean T Allen wrote:> Adam M. wrote: > >> Sean T Allen wrote: >> >> >> >>> I''ve tried tackling this many ways on my own and can''t find a good >>> solution: >>> >>> Breaking it down to something simplier... >>> >>> Venue >>> has one address >>> >>> Person >>> has one address >>> >>> Address >>> belongs to state >>> >> >> >> >> I think this is more of an inheritance problem. More of an Address is a >> Venue or Address is a Person. Then you can create a models like that, >> one derived from another. You can also do this in PostgreSQL database - >> have one table inherited from another. I don''t know how to do this and >> maintain integrity in MySQL database unless you want complex foreign >> keys in the database. Ugly.. >> >> Anyway, has_one is suppose to be a 1-1 relationship so, >> >> A >> has_one :address >> >> Address >> belongs_to :a >> >> Anything else will not work very well with has_one, belongs_to. >> >> > Don''t think I totally follow this... > > can you give a quick snippet of code for say A and as well a class > that derives from it... > I tried playing around with something like that but couldn''t get it to > work at all...You would need to use something like PostgreSQL (not sure about other databases, but MySQL doesn''t have it) so you would create table Addresses and have Person and Venue inherit from that. In the model, I would then have (you probably want separate files and maybe `require ''address''` would be required :), class Address < ActiveRecord::Base self.table_name = ''address_table'' end class Person < Address self.table_name = ''person_table'' end class Venue < Address self.table_name = ''venue_table'' end The advantages of inheritance in the database as well as the model in Ruby would be that when you insert a new Person, a new Address would also be created (in the database, not by AR). Again, something like this *will not* work correctly unless you use PostgreSQL. I''m not sure if Oracle has inheritance of tables, but I''m sure you could create something compatible. MySQL will not work for this scenario (ie. my solution) This also avoids using any "belongs_to" or other Rails relationship functions since none are needed. The only disadvantage is that you cannot easily create an Address and then assign a Person/Venue to it. To "assign" an address already in the database you would have to, 1. Get the Address record 2. Person.new and assign the Address'' values to that Person. 3. Delete Address from #1 4. Save the new person. All of this can be done as one database transaction, so not a problem. - Adam PS. The table_name are just in case you need them as well as for clarity.
Adam Majer wrote:>Sean T Allen wrote: > > > >>Adam M. wrote: >> >> >> >>>Sean T Allen wrote: >>> >>> >>> >>> >>> >>>>I''ve tried tackling this many ways on my own and can''t find a good >>>>solution: >>>> >>>>Breaking it down to something simplier... >>>> >>>>Venue >>>>has one address >>>> >>>>Person >>>>has one address >>>> >>>>Address >>>>belongs to state >>>> >>>> >>>> >>> >>>I think this is more of an inheritance problem. More of an Address is a >>>Venue or Address is a Person. Then you can create a models like that, >>>one derived from another. You can also do this in PostgreSQL database - >>>have one table inherited from another. I don''t know how to do this and >>>maintain integrity in MySQL database unless you want complex foreign >>>keys in the database. Ugly.. >>> >>>Anyway, has_one is suppose to be a 1-1 relationship so, >>> >>>A >>> has_one :address >>> >>>Address >>> belongs_to :a >>> >>>Anything else will not work very well with has_one, belongs_to. >>> >>> >>> >>> >>Don''t think I totally follow this... >> >>can you give a quick snippet of code for say A and as well a class >>that derives from it... >>I tried playing around with something like that but couldn''t get it to >>work at all... >> >> > >You would need to use something like PostgreSQL (not sure about other >databases, but MySQL doesn''t have it) so you would create table >Addresses and have Person and Venue inherit from that. > >In the model, I would then have (you probably want separate files and >maybe `require ''address''` would be required :), > >class Address < ActiveRecord::Base > self.table_name = ''address_table'' >end > >class Person < Address > self.table_name = ''person_table'' >end > >class Venue < Address > self.table_name = ''venue_table'' >end > >The advantages of inheritance in the database as well as the model in >Ruby would be that when you insert a new Person, a new Address would >also be created (in the database, not by AR). > >Again, something like this *will not* work correctly unless you use >PostgreSQL. I''m not sure if Oracle has inheritance of tables, but I''m >sure you could create something compatible. MySQL will not work for this >scenario (ie. my solution) > >This also avoids using any "belongs_to" or other Rails relationship >functions since none are needed. The only disadvantage is that you >cannot easily create an Address and then assign a Person/Venue to it. To >"assign" an address already in the database you would have to, > >1. Get the Address record >2. Person.new and assign the Address'' values to that Person. >3. Delete Address from #1 >4. Save the new person. > >All of this can be done as one database transaction, so not a problem. > >- Adam > >PS. The table_name are just in case you need them as well as for clarity. > > >Yeah I figure that out while I was sleeping because when I got up this morning it made sense... have been running with using it for has_many relationships where anythings that has an address ( or addresses ) inherits from address_entity which just has an id... so Company, Person, Venue all inherit from address_entity and then the addresses table entries have a foreign_key pointing to the proper owner. Very nice. Thanks for the help... MySQL gets ditched... Postgresql and Adam give me the solution to a problem thats been bugging me with every app I do as a learning experience... _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Regarding the inheritance in PostgreSQL, I would stay away from doing inheritance. From what I''ve read, the primary keys can get tricky and not perform as expected. For example: create table1( id serial primary key, descr varchar(20) ); create table2( other_data varchar(30) ) inherits (table1); insert into table1(descr) values(''description 1''); insert into table1(descr) values(''description 2''); select * from table1;> 1, description 1 > 2, description 2insert into table2(id,descr, other_data) values (2, ''description 3'', ''other data''); select id,descr from table1;>1, description 1 >2, description 3 >2, description 2The primary key can get hosed. I went a different route: create table1( id serial primary key, descr varchar(20) ); create table2( id integer primary key references table1(id), specific_data varchar(20) ); This way I store all my common information in table1 and specific information in table2. I would imagine rails would be able to handle this sort of setup quite easily. (Not tested.) Just my .02, andy -- Andrew Stone
Andrew Stone wrote:>Regarding the inheritance in PostgreSQL, I would stay away from doing >inheritance. From what I''ve read, the primary keys can get tricky and >not perform as expected. > >For example: > >create table1( > id serial primary key, > descr varchar(20) >); > > >create table2( > other_data varchar(30) >) inherits (table1); > >insert into table1(descr) values(''description 1''); >insert into table1(descr) values(''description 2''); > >select * from table1; > > >>1, description 1 >>2, description 2 >> >> > >insert into table2(id,descr, other_data) values (2, ''description 3'', >''other data''); > >select id,descr from table1; > > >>1, description 1 >>2, description 3 >>2, description 2 >> >> > >The primary key can get hosed. > > >Why on earth would it be implemented like that? It doesnt carry the uniqueness of the primary key over? Well I suppose I can see reasons for it...>I went a different route: > >create table1( > id serial primary key, > descr varchar(20) >); > >create table2( > id integer primary key references table1(id), > specific_data varchar(20) >); > >This way I store all my common information in table1 and specific >information in table2. > >I would imagine rails would be able to handle this sort of setup quite >easily. (Not tested.) > >I tried something like this before and ran into problems... don''t remember exactly what they were but it got ugly... _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
On 5/13/05, Sean T Allen <sean-5W9FBhQXBOtBDgjK7y7TUQ@public.gmane.org> wrote:> Andrew Stone wrote: > > >Regarding the inheritance in PostgreSQL, I would stay away from doing > >inheritance. From what I''ve read, the primary keys can get tricky and > >not perform as expected. > > > >For example: > > > >create table1( > > id serial primary key, > > descr varchar(20) > >); > > > > > >create table2( > > other_data varchar(30) > >) inherits (table1); > > > >insert into table1(descr) values(''description 1''); > >insert into table1(descr) values(''description 2''); > > > >select * from table1; > > > > > >>1, description 1 > >>2, description 2 > >> > >> > > > >insert into table2(id,descr, other_data) values (2, ''description 3'', > >''other data''); > > > >select id,descr from table1; > > > > > >>1, description 1 > >>2, description 3 > >>2, description 2 > >> > >> > > > >The primary key can get hosed. > > > > > > > > Why on earth would it be implemented like that? > > It doesnt carry the uniqueness of the primary key over? > > Well I suppose I can see reasons for it... > > >I went a different route: > > > >create table1( > > id serial primary key, > > descr varchar(20) > >); > > > >create table2( > > id integer primary key references table1(id), > > specific_data varchar(20) > >); > > > >This way I store all my common information in table1 and specific > >information in table2. > > > >I would imagine rails would be able to handle this sort of setup quite > >easily. (Not tested.) > > > > > I tried something like this before and ran into problems... don''t > remember exactly what they > were but it got ugly... > > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > > >Why on earth would I want something that is not itself an address to inherit from an address? A Person is not an Address, nor is an Address a Person, so why model it that way? No one has yet provided any justification as to why a belongs_to relation is undesirable in this situation. Maybe I''m being naive, but it seems like trying to hammer a nail with a spoon! Jason
create table address (id ... primary key, ...) create table person (..., addressid as integer) create table venue (..., addressid as integer) Then, it''s simple for AR: model Person has_a :address ... model Venue has_a :address ... model Address belongs_to :person belongs_to :venue ... The ERD would be something like this: Person <<---> Address Venue <<---> Address or OCL-ish Person (0.*) --PersonAddress--- (0..1) Address Venue (0..*) --VenueAddress-- (0..1) Address More abstractly, a Person or Venue could be defined as an "Entity". This would, of course, allow a Person or Venue to have multiple addresses (and, presumably, address types, address history, etc). In the real world, it doesn''t matter if a Person and Venue have the same address. George Steinbrenner''s address is probably "161st St. and River Ave, Bronx, NY", the same as it is for Yankee Stadium. The thing you can''t model with this ERD, though, is George, Elaine and Cramer also sharing Jerry''s address half of the time, nor George''s under-desk bed. On 5/13/05, Sean T Allen <sean-5W9FBhQXBOtBDgjK7y7TUQ@public.gmane.org> wrote:> Andrew Stone wrote: > > >Regarding the inheritance in PostgreSQL, I would stay away from doing > >inheritance. From what I''ve read, the primary keys can get tricky and > >not perform as expected. > > > >For example: > > > >create table1( > > id serial primary key, > > descr varchar(20) > >); > > > > > >create table2( > > other_data varchar(30) > >) inherits (table1); > > > >insert into table1(descr) values(''description 1''); > >insert into table1(descr) values(''description 2''); > > > >select * from table1; > > > > > >>1, description 1 > >>2, description 2 > >> > >> > > > >insert into table2(id,descr, other_data) values (2, ''description 3'', > >''other data''); > > > >select id,descr from table1; > > > > > >>1, description 1 > >>2, description 3 > >>2, description 2 > >> > >> > > > >The primary key can get hosed. > > > > > > > > Why on earth would it be implemented like that? > > It doesnt carry the uniqueness of the primary key over? > > Well I suppose I can see reasons for it... > > >I went a different route: > > > >create table1( > > id serial primary key, > > descr varchar(20) > >); > > > >create table2( > > id integer primary key references table1(id), > > specific_data varchar(20) > >); > > > >This way I store all my common information in table1 and specific > >information in table2. > > > >I would imagine rails would be able to handle this sort of setup quite > >easily. (Not tested.) > > > > > I tried something like this before and ran into problems... don''t > remember exactly what they > were but it got ugly... > > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > > >
Corey Lawson wrote:>create table address (id ... primary key, ...) > >create table person (..., addressid as integer) >create table venue (..., addressid as integer) > >Then, it''s simple for AR: > >model Person > has_a :address > ... > > >I wasnt aware of any has_a association in rails... and wouldnt that be a belongs_to because the addressid is in the person table? _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Jason Foreman wrote:>Why on earth would I want something that is not itself an address to >inherit from an address? A Person is not an Address, nor is an >Address a Person, so why model it that way? > >No one has yet provided any justification as to why a belongs_to >relation is undesirable in this situation. Maybe I''m being naive, but >it seems like trying to hammer a nail with a spoon! > >I can see that... the inheritaning from an ''entity'' tho works for me in that it gives flexibility in either has_one or has_many relationships which belongs_to doesnt give. _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Andrew Stone wrote:>Regarding the inheritance in PostgreSQL, I would stay away from doing >inheritance. From what I''ve read, the primary keys can get tricky and >not perform as expected. > >That''s why you have, base_table { id serial primary key, ... } and then when you inherit from it, it inherits the id as well. Anytime you do an insert, the id gets incremented (it is a sequence in PostgreSQL and does not belong to any table). So unless you actually use primary keys (not very useful in case of Address/Person/Venue anyway) to store data, your scenario cannot occur. But I do agree that people should know what they are doing about primary keys when using inheritance. - Adam
Corey Lawson wrote:>create table address (id ... primary key, ...) > >create table person (..., addressid as integer) >create table venue (..., addressid as integer) > >Then, it''s simple for AR: > >model Person > has_a :address > ... > >model Venue > has_a :address > ... > >model Address > belongs_to :person > belongs_to :venue > ... > >has_a function appears not yet documented and not in 0.12.1 (checked sources). There are problems with Address though since you don''t know what it actually belongs to. You have to check both person and venue. An address probably doesn''t belong to a person (assuming residence) AND a venue. Anyway, this would be a different solution that would work with all databases. One just has to make sure to have indexes on the addressid column in person and venues tables! - Adam
I''m sure that Corey meant "has_one." Here''s a question, though -- shouldn''t the Person belongs_to an Address, and an Address have_many People? ''cuz otherwise, I''m going to have to kick the wife and son out when I get home :) Regards, Phillip On 5/13/05, Adam M. <gnuman1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Corey Lawson wrote: > > >create table address (id ... primary key, ...) > > > >create table person (..., addressid as integer) > >create table venue (..., addressid as integer) > > > >Then, it''s simple for AR: > > > >model Person > > has_a :address > > ... > > > >model Venue > > has_a :address > > ... > > > >model Address > > belongs_to :person > > belongs_to :venue > > ... > > > > > > has_a function appears not yet documented and not in 0.12.1 (checked > sources). > > There are problems with Address though since you don''t know what it > actually belongs to. You have to check both person and venue. An address > probably doesn''t belong to a person (assuming residence) AND a venue. > > Anyway, this would be a different solution that would work with all > databases. One just has to make sure to have indexes on the addressid > column in person and venues tables! > > - Adam > > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Phillip J. Birmingham Software Engineer PJB Software http://pjbsoftware.com
Sorry. has_a instead of has_one. My bad. from the source: # belongs_to :portfolio # has_one :project_manager # has_many :milestones # has_and_belongs_to_many :categories Sorry for the confusion.>From the model being modeled, a Person or Venue can have (0..1) Addresses.Because the Person and Venue tables presumably have the addressid field, then they don''t "belong_to" the Address, they "has_one". The Address in this case can belong_to a (any) Person or a Venue. On 5/13/05, Sean T Allen <sean-5W9FBhQXBOtBDgjK7y7TUQ@public.gmane.org> wrote:> Corey Lawson wrote: > > >create table address (id ... primary key, ...) > > > >create table person (..., addressid as integer) > >create table venue (..., addressid as integer) > > > >Then, it''s simple for AR: > > > >model Person > > has_a :address > > ... > > > > > > > I wasnt aware of any has_a association in rails... > > and wouldnt that be a belongs_to because the addressid is in the person > table? > > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > > >
On 5/13/05, Phillip Birmingham <pbirmingham-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I''m sure that Corey meant "has_one." > > Here''s a question, though -- shouldn''t the Person belongs_to an > Address, and an Address have_many People? ''cuz otherwise, I''m going > to have to kick the wife and son out when I get home :)No. Then you would want (need) a personid and venueid in your Address table. The address really is just an attribute of a person or venue. You store the details of the address once, and attribute the address to persons and venues (ala the addressid in the Person and Venue tables).> > Regards, > Phillip > > > On 5/13/05, Adam M. <gnuman1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Corey Lawson wrote: > > > > >create table address (id ... primary key, ...) > > > > > >create table person (..., addressid as integer) > > >create table venue (..., addressid as integer) > > > > > >Then, it''s simple for AR: > > > > > >model Person > > > has_a :address > > > ... > > > > > >model Venue > > > has_a :address > > > ... > > > > > >model Address > > > belongs_to :person > > > belongs_to :venue > > > ... > > > > > > > > > > has_a function appears not yet documented and not in 0.12.1 (checked > > sources). > > > > There are problems with Address though since you don''t know what it > > actually belongs to. You have to check both person and venue. An address > > probably doesn''t belong to a person (assuming residence) AND a venue. > > > > Anyway, this would be a different solution that would work with all > > databases. One just has to make sure to have indexes on the addressid > > column in person and venues tables! > > > > - Adam > > > > > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > -- > Phillip J. Birmingham > Software Engineer > PJB Software > http://pjbsoftware.com > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
On 5/13/05, Corey Lawson <corey.ssf.lawson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Sorry. has_a instead of has_one. My bad. > > from the source: > # belongs_to :portfolio > # has_one :project_manager > # has_many :milestones > # has_and_belongs_to_many :categories > > Sorry for the confusion. > > >From the model being modeled, a Person or Venue can have (0..1) Addresses. > Because the Person and Venue tables presumably have the addressid > field, then they don''t "belong_to" the Address, they "has_one". > > The Address in this case can belong_to a (any) Person or a Venue.This is incorrect. The table/Model with the foreign key field is the one that "belongs_to" the other one, therefore if the table people has an address_id then Person belongs_to :address. I again stress to NOT read anything more into the words "belongs_to" other than that it defines a relation between models. Conceptually, a person does not belong to an address, it seems that the address belongs to a person, however this meaning is _unrelated_ to the fact that the model is defined using those terms. "belongs_to" does not imply ownership or servitude or anything like that; it simply defines a relationship that says this model is related to that one, and this one has the key to identify the relation. Jason