I''m trying to figure out an elegant way to do this: I have the following three tables: people, employer, employees And consequently the following three models: class Person < ActiveRecord::Base end class Employer < ActiveRecord::Base has_many :employees end class Employee < ActiveRecord::Base belongs_to :person belongs_to :employer end I want to be able to say: @employee.lastname, instead of saying @employee.person.lastname Do I need to write individual method_missing''s for all of the person attributes in Employee to forward the .lastname and .firstname calls onto the :person association? Is there a smarter less brittle way? Thanks Joerg -- Posted via http://www.ruby-forum.com/.
Hi -- On Mon, 17 Jul 2006, Joerg Diekmann wrote:> I''m trying to figure out an elegant way to do this: > > I have the following three tables: > > people, employer, employees > > And consequently the following three models: > > > class Person < ActiveRecord::Base > end > > class Employer < ActiveRecord::Base > has_many :employees > end > > class Employee < ActiveRecord::Base > belongs_to :person > belongs_to :employer > end > > > I want to be able to say: @employee.lastname, instead of saying > @employee.person.lastname > > Do I need to write individual method_missing''s for all of the person > attributes in Employee to forward the .lastname and .firstname calls > onto the :person association? Is there a smarter less brittle way?If you want a method, just write it: class Employee < ActiveRecord::Base ... def lastname person.lastname end # etc. end Then you don''t have to worry about method_missing because it isn''t missing :-) (I''m not clear on why an Employee belongs to a Person, but that''s a different matter.) David -- http://www.rubypowerandlight.com => Ruby/Rails training & consultancy http://www.manning.com/black => RUBY FOR RAILS (reviewed on Slashdot, 7/12/2006!) http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log dblack@wobblini.net => me
I guess you should be using just one table and achieve the functionality using STI ( single table inheritance ) and self referential joins. -Pratik On 7/17/06, Joerg Diekmann <joergd@pobox.com> wrote:> I''m trying to figure out an elegant way to do this: > > I have the following three tables: > > people, employer, employees > > And consequently the following three models: > > > class Person < ActiveRecord::Base > end > > class Employer < ActiveRecord::Base > has_many :employees > end > > class Employee < ActiveRecord::Base > belongs_to :person > belongs_to :employer > end > > > I want to be able to say: @employee.lastname, instead of saying > @employee.person.lastname > > Do I need to write individual method_missing''s for all of the person > attributes in Employee to forward the .lastname and .firstname calls > onto the :person association? Is there a smarter less brittle way? > > Thanks > Joerg > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- rm -rf / 2>/dev/null - http://null.in "Things do not happen. Things are made to happen." - JFK
I wanted to exploit missing_method in some way, so that I don''t have to write a whole lot of extra methods like you described. Also, as my Person model grows, I want all these attributes to be automagically available. The Employee model is basically the model to describe the relationship between a person and an employer. In it I can record extra employee specific data. I also have other types of people, like contacts etc. I thought of not going the STI route, in case we want to store all the people in an LDAP directory ... Plus, by having an employee model (separate from a person model), allows me to create RESTful URLS more easily - ie I''m giving the person context wrt to an employer within the URL structure. Dunno - am I being to abstract about it all? Joerg unknown wrote:> Hi -- > > On Mon, 17 Jul 2006, Joerg Diekmann wrote: > >> end >> >> I want to be able to say: @employee.lastname, instead of saying >> @employee.person.lastname >> >> Do I need to write individual method_missing''s for all of the person >> attributes in Employee to forward the .lastname and .firstname calls >> onto the :person association? Is there a smarter less brittle way? > > If you want a method, just write it: > > class Employee < ActiveRecord::Base > ... > def lastname > person.lastname > end > > # etc. > end > > Then you don''t have to worry about method_missing because it isn''t > missing :-) > > (I''m not clear on why an Employee belongs to a Person, but that''s a > different matter.) > > > David > > -- > http://www.rubypowerandlight.com => Ruby/Rails training & consultancy > http://www.manning.com/black => RUBY FOR RAILS (reviewed on > Slashdot, 7/12/2006!) > http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log > dblack@wobblini.net => me-- Posted via http://www.ruby-forum.com/.
On 7/17/06, Joerg Diekmann <joergd@pobox.com> wrote:> > I wanted to exploit missing_method in some way, so that I don''t have to > write a whole lot of extra methods like you described. Also, as my > Person model grows, I want all these attributes to be automagically > available. > > The Employee model is basically the model to describe the relationship > between a person and an employer. In it I can record extra employee > specific data. I also have other types of people, like contacts etc. I > thought of not going the STI route, in case we want to store all the > people in an LDAP directory ... > > Plus, by having an employee model (separate from a person model), allows > me to create RESTful URLS more easily - ie I''m giving the person context > wrt to an employer within the URL structure. > > Dunno - am I being to abstract about it all? > > Joerg > > unknown wrote: > > Hi -- > > > > On Mon, 17 Jul 2006, Joerg Diekmann wrote: > > > >> end > >> > >> I want to be able to say: @employee.lastname, instead of saying > >> @employee.person.lastname > >> > >> Do I need to write individual method_missing''s for all of the person > >> attributes in Employee to forward the .lastname and .firstname calls > >> onto the :person association? Is there a smarter less brittle way? > > > > If you want a method, just write it: > > > > class Employee < ActiveRecord::Base > > ... > > def lastname > > person.lastname > > end > > > > # etc. > > end > > > > Then you don''t have to worry about method_missing because it isn''t > > missing :-) > > > > (I''m not clear on why an Employee belongs to a Person, but that''s a > > different matter.) > > > > > > David > > > > -- > > http://www.rubypowerandlight.com => Ruby/Rails training & consultancy > > http://www.manning.com/black => RUBY FOR RAILS (reviewed on > > Slashdot, 7/12/2006!) > > http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log > > dblack@wobblini.net => me > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/railsDavid, Is there a problem with using method missing in situations like this? In your book, you show how to do it, does this mean that perhaps it shouldn''t be done? Just Curious Dan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060717/490f198b/attachment.html
Hi -- On Mon, 17 Jul 2006, Joerg Diekmann wrote:> I wanted to exploit missing_method in some way, so that I don''t have to > write a whole lot of extra methods like you described. Also, as my > Person model grows, I want all these attributes to be automagically > available.To me it sounds like a sign that the domain model isn''t right. The fact that Employee needs the same behavior as Person suggests a subclassing relationship.> The Employee model is basically the model to describe the relationship > between a person and an employer. In it I can record extra employee > specific data. I also have other types of people, like contacts etc. I > thought of not going the STI route, in case we want to store all the > people in an LDAP directory ...The word "employee" definitely means a person, not a relationship between a person and a company. If you want to model the relationship, you should probably call it a position, or a hiring, or something like that. That would also force the issue of clarifying what''s a person and what isn''t.> Plus, by having an employee model (separate from a person model), allows > me to create RESTful URLS more easily - ie I''m giving the person context > wrt to an employer within the URL structure.(I''ll leave that part to you; I''m still working on figuring out why I''m supposed to care about URLs so much :-)> Dunno - am I being to abstract about it all?I just think "employee" is the wrong concept for a relationship between a person and an employer, and that the need for method_missing is a sign that the domain model isn''t right. David> Joerg > > unknown wrote: > >> Hi -- >> >> On Mon, 17 Jul 2006, Joerg Diekmann wrote: >> >>> end >>> >>> I want to be able to say: @employee.lastname, instead of saying >>> @employee.person.lastname >>> >>> Do I need to write individual method_missing''s for all of the person >>> attributes in Employee to forward the .lastname and .firstname calls >>> onto the :person association? Is there a smarter less brittle way? >> >> If you want a method, just write it: >> >> class Employee < ActiveRecord::Base >> ... >> def lastname >> person.lastname >> end >> >> # etc. >> end >> >> Then you don''t have to worry about method_missing because it isn''t >> missing :-) >> >> (I''m not clear on why an Employee belongs to a Person, but that''s a >> different matter.) >> >> >> David >> >> -- >> http://www.rubypowerandlight.com => Ruby/Rails training & consultancy >> http://www.manning.com/black => RUBY FOR RAILS (reviewed on >> Slashdot, 7/12/2006!) >> http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log >> dblack@wobblini.net => me > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- http://www.rubypowerandlight.com => Ruby/Rails training & consultancy http://www.manning.com/black => RUBY FOR RAILS (reviewed on Slashdot, 7/12/2006!) http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log dblack@wobblini.net => me
On Mon, 17 Jul 2006, Daniel N wrote:> David, > > Is there a problem with using method missing in situations like this? > > In your book, you show how to do it, does this mean that perhaps it > shouldn''t be done?I do talk about it in the book, though as I re-read those pages I see that I seem to be presenting it mostly in the light of something that Rails uses a lot in its own source code. And I give only non-Rails examples of how to use it. That might have reflected a subconscious feeling that using it in AR model files is potentially problematic :-) I do think that if you''re systematically sending messages from one model to another, it''s a strong sign that the domain model needs some redesign. Having created a domain model, you shouldn''t need to circumvent it, so to speak. David -- http://www.rubypowerandlight.com => Ruby/Rails training & consultancy http://www.manning.com/black => RUBY FOR RAILS (reviewed on Slashdot, 7/12/2006!) http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log dblack@wobblini.net => me
Now - what if I have contacts too. So an employer has employees and contacts. Both are people. And both relate back to the employer. I could use STI and store everything in a people table. But then a person can only either be an employee or a contact - but not both. That is if I am using the automagic column ''type''. I suppose I could also skip the ''type'' column and create isEmployee and isContact columns to handle this but it kinda makes things a bit ugly. The other alternative is to have an employees and a contacts table, and both have the firstname lastname, all the address fields and tel numbers etc duplicated. So there are two place in the app where a ''person'' is defined. Also I''ll end up with duplicate data, in the case where a person can be both a contact and an employee of an employer. Therefore my thinking was that both contacts and employees are people (stored in the people table), and their relationship to the employer is represented by the employees and the contacts table. Anyway. unknown wrote:> Hi -- > > On Mon, 17 Jul 2006, Joerg Diekmann wrote: > >> I wanted to exploit missing_method in some way, so that I don''t have to >> write a whole lot of extra methods like you described. Also, as my >> Person model grows, I want all these attributes to be automagically >> available. > > To me it sounds like a sign that the domain model isn''t right. The > fact that Employee needs the same behavior as Person suggests a > subclassing relationship. > >> The Employee model is basically the model to describe the relationship >> between a person and an employer. In it I can record extra employee >> specific data. I also have other types of people, like contacts etc. I >> thought of not going the STI route, in case we want to store all the >> people in an LDAP directory ... > > The word "employee" definitely means a person, not a relationship > between a person and a company. If you want to model the > relationship, you should probably call it a position, or a hiring, or > something like that. That would also force the issue of clarifying > what''s a person and what isn''t. > >> Plus, by having an employee model (separate from a person model), allows >> me to create RESTful URLS more easily - ie I''m giving the person context >> wrt to an employer within the URL structure. > > (I''ll leave that part to you; I''m still working on figuring out why > I''m supposed to care about URLs so much :-) > >> Dunno - am I being to abstract about it all? > > I just think "employee" is the wrong concept for a relationship > between a person and an employer, and that the need for method_missing > is a sign that the domain model isn''t right. > > > David > >>>> I want to be able to say: @employee.lastname, instead of saying >>> def lastname >>> different matter.) >> >> >> -- >> Posted via http://www.ruby-forum.com/. >> _______________________________________________ >> Rails mailing list >> Rails@lists.rubyonrails.org >> http://lists.rubyonrails.org/mailman/listinfo/rails >> > > -- > http://www.rubypowerandlight.com => Ruby/Rails training & consultancy > http://www.manning.com/black => RUBY FOR RAILS (reviewed on > Slashdot, 7/12/2006!) > http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log > dblack@wobblini.net => me-- Posted via http://www.ruby-forum.com/.
How about this? people (id, firstname, lastname) employment(id, boss_id, employee_id) contactship (id, contacter_id, contactee_id) then use self referential has_many :through a la... http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through This way a person can have several bosses and employees and contacts all at the same time. Also the real world object of a person is only modeled once. Peter On 7/17/06, Joerg Diekmann <joergd@pobox.com> wrote:> Now - what if I have contacts too. So an employer has employees and > contacts. Both are people. And both relate back to the employer. I could > use STI and store everything in a people table. But then a person can > only either be an employee or a contact - but not both. That is if I am > using the automagic column ''type''. I suppose I could also skip the > ''type'' column and create isEmployee and isContact columns to handle this > but it kinda makes things a bit ugly. > > The other alternative is to have an employees and a contacts table, and > both have the firstname lastname, all the address fields and tel numbers > etc duplicated. So there are two place in the app where a ''person'' is > defined. Also I''ll end up with duplicate data, in the case where a > person can be both a contact and an employee of an employer. > > Therefore my thinking was that both contacts and employees are people > (stored in the people table), and their relationship to the employer is > represented by the employees and the contacts table. > > Anyway. > > unknown wrote: > > Hi -- > > > > On Mon, 17 Jul 2006, Joerg Diekmann wrote: > > > >> I wanted to exploit missing_method in some way, so that I don''t have to > >> write a whole lot of extra methods like you described. Also, as my > >> Person model grows, I want all these attributes to be automagically > >> available. > > > > To me it sounds like a sign that the domain model isn''t right. The > > fact that Employee needs the same behavior as Person suggests a > > subclassing relationship. > > > >> The Employee model is basically the model to describe the relationship > >> between a person and an employer. In it I can record extra employee > >> specific data. I also have other types of people, like contacts etc. I > >> thought of not going the STI route, in case we want to store all the > >> people in an LDAP directory ... > > > > The word "employee" definitely means a person, not a relationship > > between a person and a company. If you want to model the > > relationship, you should probably call it a position, or a hiring, or > > something like that. That would also force the issue of clarifying > > what''s a person and what isn''t. > > > >> Plus, by having an employee model (separate from a person model), allows > >> me to create RESTful URLS more easily - ie I''m giving the person context > >> wrt to an employer within the URL structure. > > > > (I''ll leave that part to you; I''m still working on figuring out why > > I''m supposed to care about URLs so much :-) > > > >> Dunno - am I being to abstract about it all? > > > > I just think "employee" is the wrong concept for a relationship > > between a person and an employer, and that the need for method_missing > > is a sign that the domain model isn''t right. > > > > > > David > > > >>>> I want to be able to say: @employee.lastname, instead of saying > >>> def lastname > >>> different matter.) > >> > >> > >> -- > >> Posted via http://www.ruby-forum.com/. > >> _______________________________________________ > >> Rails mailing list > >> Rails@lists.rubyonrails.org > >> http://lists.rubyonrails.org/mailman/listinfo/rails > >> > > > > -- > > http://www.rubypowerandlight.com => Ruby/Rails training & consultancy > > http://www.manning.com/black => RUBY FOR RAILS (reviewed on > > Slashdot, 7/12/2006!) > > http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log > > dblack@wobblini.net => me > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
He has that now... the problem is he doesn''t want to write: Name: <%= @employee.person.firstname + " " + @employee.person.lastname %> Here is a VERY GOOFY idea... create an act_as_delegate mixin. class Employee < ActiveRecord::Base act_as_delegate :to => :person end and this way your method_missing''s will have something to point to first, IE the act_as_delegate will check the Person class. But this all seems a tad wonky perverse and has an odor of wrongness... Definitely utilize Peter''s structure, but this act_as_delegate thingy could work. I have this odd feeling that this is built into Ruby already, I just don''t know where to look to find it... On 7/17/06, Peter Michaux <petermichaux@gmail.com> wrote:> How about this? > > people (id, firstname, lastname) > employment(id, boss_id, employee_id) > contactship (id, contacter_id, contactee_id) > > then use self referential has_many :through a la... > > http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through > > This way a person can have several bosses and employees and contacts > all at the same time. Also the real world object of a person is only > modeled once. > > Peter > > > > On 7/17/06, Joerg Diekmann <joergd@pobox.com> wrote: > > Now - what if I have contacts too. So an employer has employees and > > contacts. Both are people. And both relate back to the employer. I could > > use STI and store everything in a people table. But then a person can > > only either be an employee or a contact - but not both. That is if I am > > using the automagic column ''type''. I suppose I could also skip the > > ''type'' column and create isEmployee and isContact columns to handle this > > but it kinda makes things a bit ugly. > > > > The other alternative is to have an employees and a contacts table, and > > both have the firstname lastname, all the address fields and tel numbers > > etc duplicated. So there are two place in the app where a ''person'' is > > defined. Also I''ll end up with duplicate data, in the case where a > > person can be both a contact and an employee of an employer. > > > > Therefore my thinking was that both contacts and employees are people > > (stored in the people table), and their relationship to the employer is > > represented by the employees and the contacts table. > > > > Anyway. > > > > unknown wrote: > > > Hi -- > > > > > > On Mon, 17 Jul 2006, Joerg Diekmann wrote: > > > > > >> I wanted to exploit missing_method in some way, so that I don''t have to > > >> write a whole lot of extra methods like you described. Also, as my > > >> Person model grows, I want all these attributes to be automagically > > >> available. > > > > > > To me it sounds like a sign that the domain model isn''t right. The > > > fact that Employee needs the same behavior as Person suggests a > > > subclassing relationship. > > > > > >> The Employee model is basically the model to describe the relationship > > >> between a person and an employer. In it I can record extra employee > > >> specific data. I also have other types of people, like contacts etc. I > > >> thought of not going the STI route, in case we want to store all the > > >> people in an LDAP directory ... > > > > > > The word "employee" definitely means a person, not a relationship > > > between a person and a company. If you want to model the > > > relationship, you should probably call it a position, or a hiring, or > > > something like that. That would also force the issue of clarifying > > > what''s a person and what isn''t. > > > > > >> Plus, by having an employee model (separate from a person model), allows > > >> me to create RESTful URLS more easily - ie I''m giving the person context > > >> wrt to an employer within the URL structure. > > > > > > (I''ll leave that part to you; I''m still working on figuring out why > > > I''m supposed to care about URLs so much :-) > > > > > >> Dunno - am I being to abstract about it all? > > > > > > I just think "employee" is the wrong concept for a relationship > > > between a person and an employer, and that the need for method_missing > > > is a sign that the domain model isn''t right. > > > > > > > > > David > > > > > >>>> I want to be able to say: @employee.lastname, instead of saying > > >>> def lastname > > >>> different matter.) > > >> > > >> > > >> -- > > >> Posted via http://www.ruby-forum.com/. > > >> _______________________________________________ > > >> Rails mailing list > > >> Rails@lists.rubyonrails.org > > >> http://lists.rubyonrails.org/mailman/listinfo/rails > > >> > > > > > > -- > > > http://www.rubypowerandlight.com => Ruby/Rails training & consultancy > > > http://www.manning.com/black => RUBY FOR RAILS (reviewed on > > > Slashdot, 7/12/2006!) > > > http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log > > > dblack@wobblini.net => me > > > > > > -- > > Posted via http://www.ruby-forum.com/. > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Hi -- On Mon, 17 Jul 2006, Carl Fyffe wrote:> > On 7/17/06, Peter Michaux <petermichaux@gmail.com> wrote: >> How about this? >> >> people (id, firstname, lastname) >> employment(id, boss_id, employee_id) >> contactship (id, contacter_id, contactee_id) >> >> then use self referential has_many :through a la... >> >> http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through >> >> This way a person can have several bosses and employees and contacts >> all at the same time. Also the real world object of a person is only >> modeled once. >> >> Peter >> > He has that now... the problem is he doesn''t want to write: > > Name: <%= @employee.person.firstname + " " + @employee.person.lastname %>But that''s because Joerg has the intermediate table named "employee", when it really needs a non-human name, and that obscures the fact that the relation between employer and employee is not, itself, a person. You want something like: class Employer has_many :employees, :through => :positions, :source => :person where the positions table has employer_id and person_id. Then you can do things like: @employer = Employer.find(params[:id]) @employees = @employer.employees ... <% @employees.each do |employee| %> <%= employee.firstname %> ... ... <% end %> David -- http://www.rubypowerandlight.com => Ruby/Rails training & consultancy http://www.manning.com/black => RUBY FOR RAILS (reviewed on Slashdot, 7/12/2006!) http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log dblack@wobblini.net => me
I knew I was going into overkill mode. Thanks for the better solution David. On 7/17/06, dblack@wobblini.net <dblack@wobblini.net> wrote:> Hi -- > > On Mon, 17 Jul 2006, Carl Fyffe wrote: > > > > > On 7/17/06, Peter Michaux <petermichaux@gmail.com> wrote: > >> How about this? > >> > >> people (id, firstname, lastname) > >> employment(id, boss_id, employee_id) > >> contactship (id, contacter_id, contactee_id) > >> > >> then use self referential has_many :through a la... > >> > >> http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through > >> > >> This way a person can have several bosses and employees and contacts > >> all at the same time. Also the real world object of a person is only > >> modeled once. > >> > >> Peter > >> > > He has that now... the problem is he doesn''t want to write: > > > > Name: <%= @employee.person.firstname + " " + @employee.person.lastname %> > > But that''s because Joerg has the intermediate table named "employee", > when it really needs a non-human name, and that obscures the fact that > the relation between employer and employee is not, itself, a person. > You want something like: > > class Employer > has_many :employees, :through => :positions, :source => :person > > where the positions table has employer_id and person_id. Then you can > do things like: > > @employer = Employer.find(params[:id]) > @employees = @employer.employees > ... > <% @employees.each do |employee| %> > <%= employee.firstname %> ... > ... > <% end %> > > > David > > -- > http://www.rubypowerandlight.com => Ruby/Rails training & consultancy > http://www.manning.com/black => RUBY FOR RAILS (reviewed on > Slashdot, 7/12/2006!) > http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log > dblack@wobblini.net => me > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Hmmm. It makes sense to maybe label the middle table something other than employees - to be able to then use the :through directive. In this case, though - I''m not at all interested in their position at work - I''m more interested in their employee number, when they started or finished working etc. .... the ''employee'' details other than their personal details. Maybe call it employment_details or something more generic. I''ll need to think about the long term benefits from all these different solutions a little more. unknown wrote:> Hi -- > > On Mon, 17 Jul 2006, Carl Fyffe wrote: > >>> http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through >>> >>> This way a person can have several bosses and employees and contacts >>> all at the same time. Also the real world object of a person is only >>> modeled once. >>> >>> Peter >>> >> He has that now... the problem is he doesn''t want to write: >> >> Name: <%= @employee.person.firstname + " " + @employee.person.lastname %> > > But that''s because Joerg has the intermediate table named "employee", > when it really needs a non-human name, and that obscures the fact that > the relation between employer and employee is not, itself, a person. > You want something like: > > class Employer > has_many :employees, :through => :positions, :source => :person > > where the positions table has employer_id and person_id. Then you can > do things like: > > @employer = Employer.find(params[:id]) > @employees = @employer.employees > ... > <% @employees.each do |employee| %> > <%= employee.firstname %> ... > ... > <% end %> > > > David > > -- > http://www.rubypowerandlight.com => Ruby/Rails training & consultancy > http://www.manning.com/black => RUBY FOR RAILS (reviewed on > Slashdot, 7/12/2006!) > http://dablog.rubypal.com => D[avid ]A[. ]B[lack''s][ Web]log > dblack@wobblini.net => me-- Posted via http://www.ruby-forum.com/.
The only problem I now see with this is that you won''t be able to access the employee specifc properties that easily. So, if I do employee = Employer.find(1).employees.first I can get employee.firstname etc, but won''t be able to get employee.employee_number (which would be stored on the relationship table) Nor be able to do a query where I can query on attributes across the two tables. Basically - multiple table inheritance isn''t really possible yet in ActiveRecord. Perhaps the ''best'' solution - where having a SINGLE record for a person that can be multiple things like an employee or a contact etc - is to have a people table which stores ALL possible fields for personal data and employee specific data and contact specific data and any other ''role'' specific data. And have the middle relationship tables as employee_joins and contact_joins or something that hold no other information other than the fact that a person_id and an employer_id belong together. And then use the :through directive to join them to an Employer with an :employees association. Does this seem reasonable enough? Name: <%= @employee.person.firstname + " " + @employee.person.lastname %>>> >> But that''s because Joerg has the intermediate table named "employee", >> when it really needs a non-human name, and that obscures the fact that >> the relation between employer and employee is not, itself, a person. >> You want something like: >> >> class Employer >> has_many :employees, :through => :positions, :source => :person >> >> where the positions table has employer_id and person_id. Then you can >> do things like: >> >> @employer = Employer.find(params[:id]) >> @employees = @employer.employees >> ... >> <% @employees.each do |employee| %> >> <%= employee.firstname %> ... >> ... >> <% end %> >> >> >> David >>-- Posted via http://www.ruby-forum.com/.
On 7/17/06, Joerg Diekmann <joergd@pobox.com> wrote:> I want to be able to say: @employee.lastname, instead of saying > @employee.person.lastname > > Do I need to write individual method_missing''s for all of the person > attributes in Employee to forward the .lastname and .firstname calls > onto the :person association? Is there a smarter less brittle way?There''s actually a delegate method that you use for this. It doesn''t show up in the current docs because no docs were written...but if you look at http://dev.rubyonrails.org/ticket/5002 (when trac comes back up) you''ll be able to see the usage. Simple example: class Employee < AR::Base belongs_to :person delegate :first_name, :last_name, :to => :person end If you have an employee object and call employee.first_name, it delegates it to the person assocation. So there''s a more elegant way to do what you want. As others have said though, I think you might need to rework your domain model. Pat