Hello, I have a People table and a Addresses table. A person can have one or more addresses, but should at least have one, so there is a address_id field in People. Now, I would like to have a form to fill the name of a new person and its address from the same place. I could use person.address.country, for example (it works), but I would like to simply use person.country for some reasons (I have a generic controller and generic views which can make this kind of forms automatically if I give a list of fields, but it has to be directly in the model). I could add the "country" field to the model, but I have a lot of fields I would like to "import". I tried to use the :include option, but mysql complains because I have a field which has the same name in both People and Addresses table (and it should stay this way). I tried to generate model methods "on the fly" with define_method, but I''ve not been able to do it, as I couldn''t write generic code to call the corresponding method of another model. This is because I can''t know the name of the method I''m currently in. Hope this is somewhat clear ;-) So, my question is: how should I do that without writing a lot of redundant code? Thank you, -- ---------------------------------------------------------------------- Yannick Majoros http://www.inma.ucl.ac.be/~majoros Informaticien UCL/INMA-MEMA 4, avenue G. Lema?tre B-1348 Louvain-la-Neuve Tel: +32-10-47.80.10 Fax: +32-10-47.21.80 ---------------------------------------------------------------------- Mon calendrier en ligne : http://www.inma.ucl.ac.be/~majoros/calendar Accents bizarres ? http://www.inma.ucl.ac.be/~majoros/email.html ---------------------------------------------------------------------- -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3403 bytes Desc: S/MIME Cryptographic Signature Url : http://wrath.rubyonrails.org/pipermail/rails/attachments/20060705/126ee21b/smime.bin
I''m fairly new to rails, so don''t take my advice. But here it is anyway. Part of the rails ethos (IMO) is built around enforcing things like foreign key constraints in the app, and not in the database. Putting an address_id in the people table seems as though it is intended to enforce a rule that should be enforced in the application as well. If the relationship is one person to many addresses, then the data model should be exactly that - a person_id in the addresses table. You can have an "is_primary_address" column in the addresses table, or something along those lines, but the enforcement that there is at least one address should be done in the application. If you were to take that approach, the redundancy in the db would be gone and so should the redundancy in the app. As for how to handle that in the app, I think you''d be able to do something like this: <%= text_field ''person'', ''first_name'' %> ... (more person fields) ... <%= text_field, ''address'', ''street'' %> ... (more address fields) ... #People controller def create @person = Person.new(params[:person]) @person.primary_address = Address.new(params[:address]) if @person.save ... (error handling and redirect) ... end Then have the Person model take care of setting itself as the Address'' person_id and make the Address primary in the save method. This allows you to wrap the saves in a transaction, it''s all very testable at the model level, and it has none of the redundancy you''re interested in avoiding. Hope this helps. David ps - if any of you more experienced railers think this is totally out of whack, please pipe up. I''m coming from the TDD java world and trying to figure out how to swim in this sparkly, new ocean. On Jul 5, 2006, at 5:30 AM, Yannick Majoros wrote:> Hello, > > I have a People table and a Addresses table. A person can have one > or more addresses, but should at least have one, so there is a > address_id field in People. > > Now, I would like to have a form to fill the name of a new person > and its address from the same place. I could use > person.address.country, for example (it works), but I would like to > simply use person.country for some reasons (I have a generic > controller and generic views which can make this kind of forms > automatically if I give a list of fields, but it has to be directly > in the model). > > I could add the "country" field to the model, but I have a lot of > fields I would like to "import". > > I tried to use the :include option, but mysql complains because I > have a field which has the same name in both People and Addresses > table (and it should stay this way). > > I tried to generate model methods "on the fly" with define_method, > but I''ve not been able to do it, as I couldn''t write generic code > to call the corresponding method of another model. This is because > I can''t know the name of the method I''m currently in. Hope this is > somewhat clear ;-) > > So, my question is: how should I do that without writing a lot of > redundant code? > > Thank you, > > -- > ---------------------------------------------------------------------- > Yannick Majoros http://www.inma.ucl.ac.be/~majoros > Informaticien UCL/INMA-MEMA > 4, avenue G. Lema?tre > B-1348 Louvain-la-Neuve > Tel: +32-10-47.80.10 > Fax: +32-10-47.21.80 > ---------------------------------------------------------------------- > Mon calendrier en ligne : http://www.inma.ucl.ac.be/~majoros/calendar > Accents bizarres ? http://www.inma.ucl.ac.be/~majoros/email.html > ---------------------------------------------------------------------- > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails
*If* a person always has at least one address *and* you feel that, for example, country is really an attribute of person for whatever reason, you could consider adding the address fields to the person table.>From what you say about your controller working by default with a singleaddress per person, you presumably handle addresses after the first in different controller and view code. So, consider a "person" table with one set of address fields and a "further addresses" table. If your main address per person is always treated differently from the further addresses, this would work. From what you say about your controller, this would seem to be the case. This is not a normalized database design and some would consider it heresy. However, it depends on what your design represents in the real world. However, I would always, by preference, choose the simple design where tables are normalized and independent. Even if there seems to be a good reason to go away from this now, you may regret it later. You could, of course, modify your generic controller to handle a relationship like this generically. Julian -- Posted via http://www.ruby-forum.com/.
David Chelimsky wrote:> I''m fairly new to rails, so don''t take my advice. But here it is anyway. > > Part of the rails ethos (IMO) is built around enforcing things like > foreign key constraints in the app, and not in the database. Putting > an address_id in the people table seems as though it is intended to > enforce a rule that should be enforced in the application as well. If > the relationship is one person to many addresses, then the data model > should be exactly that - a person_id in the addresses table. You can > have an "is_primary_address" column in the addresses table, or > something along those lines, but the enforcement that there is at > least one address should be done in the application. If you were to > take that approach, the redundancy in the db would be gone and so > should the redundancy in the app. >Hello, Thank you for your quick answer. I don''t think there is a design problem in my db (others please correct me if you don''t think so). There is no redundancy in it, and I don''t want to enforce there is at least one address for each person in my db. Actually, address_id can be null. If it isn''t, then it has to be valid, naturally. I''ll try to put it another way. For some reason, I want to have a "country" method in my "person" model. It should look this up in Address, so I could just do this: class Person < ActiveRecord::Base has_one :address def country self.address.country if self.address end end This does what I want, but I''d like more. Besides "country", there are a lot of other methods from Address I''d like to make available in Person. I''d like to write something to do it automatically. I tried this: for col in Address.content_columns define method( col.name ) self.Address.send col.name end end But this doesn''t work fully neither, because it is only executed when it is called, so col.name in the body of the function is not set to the right column. I tried to do it by overriding ActiveRecord::find in my model to have :include = :address, but mysql does complain because I have some identical field names in People and Addresses tables (say, last_update_timestamp ), which makes the JOIN query ambigous. As I write this, I''m thinking of another option: I could write de sql query by hand... But I don''t like this solution for other reasons. What could I do? Thank you, -- ---------------------------------------------------------------------- Yannick Majoros http://www.inma.ucl.ac.be/~majoros Informaticien UCL/INMA-MEMA 4, avenue G. Lema?tre B-1348 Louvain-la-Neuve Tel: +32-10-47.80.10 Fax: +32-10-47.21.80 ---------------------------------------------------------------------- Mon calendrier en ligne : http://www.inma.ucl.ac.be/~majoros/calendar Accents bizarres ? http://www.inma.ucl.ac.be/~majoros/email.html ---------------------------------------------------------------------- -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3403 bytes Desc: S/MIME Cryptographic Signature Url : http://wrath.rubyonrails.org/pipermail/rails/attachments/20060705/a38112f0/smime.bin
Julian Gall wrote:> *If* a person always has at least one address *and* you feel that, for > example, country is really an attribute of person for whatever reason, > you could consider adding the address fields to the person table. > > >From what you say about your controller working by default with a single > address per person, you presumably handle addresses after the first in > different controller and view code. So, consider a "person" table with > one set of address fields and a "further addresses" table. If your main > address per person is always treated differently from the further > addresses, this would work. From what you say about your controller, > this would seem to be the case. > >It is not really treated differently. I should be able to list the main address and the other ones without any difference, in another context.> This is not a normalized database design and some would consider it > heresy. However, it depends on what your design represents in the real > world. > >Mmm, I don''t really agree; what I told the list is actually a simplified version of the situation, which is rather complicated. Actually, I have different models which are derived from Person, and one of them would need to have the country field calculated from Address. This is because, for some people using some specific controller, they have to be able to browse a list of "special" people and to add one, together with an address, in one operation. My generic controller and views make it simple to generate a form for all "columns" of a model. I don''t think it would be good to make it handle the relations, because I''d need to have structures to describe these very special cases. And actually, I think the approach of having a different model is good. I could be wrong, but this application begins to grow, and I need to keep things as simple as possible (I have 20+ tables which are listed and edited in similar ways, with occasionnaly some customization like this). I think this is the best I can do at this point, but it seems I just can''t write the code to generate these methods :-(> However, I would always, by preference, choose the simple design where > tables are normalized and independent.They are ;-)> Even if there seems to be a good > reason to go away from this now, you may regret it later. > > You could, of course, modify your generic controller to handle a > relationship like this generically. > >Don''t think so, see above :-( I''m a bit lost... -- ---------------------------------------------------------------------- Yannick Majoros http://www.inma.ucl.ac.be/~majoros Informaticien UCL/INMA-MEMA 4, avenue G. Lema?tre B-1348 Louvain-la-Neuve Tel: +32-10-47.80.10 Fax: +32-10-47.21.80 ---------------------------------------------------------------------- Mon calendrier en ligne : http://www.inma.ucl.ac.be/~majoros/calendar Accents bizarres ? http://www.inma.ucl.ac.be/~majoros/email.html ---------------------------------------------------------------------- -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3403 bytes Desc: S/MIME Cryptographic Signature Url : http://wrath.rubyonrails.org/pipermail/rails/attachments/20060705/f93cb421/smime.bin
On Jul 5, 2006, at 7:12 AM, Yannick Majoros wrote:> David Chelimsky wrote: >> I''m fairly new to rails, so don''t take my advice. But here it is >> anyway. >> >> Part of the rails ethos (IMO) is built around enforcing things >> like foreign key constraints in the app, and not in the database. >> Putting an address_id in the people table seems as though it is >> intended to enforce a rule that should be enforced in the >> application as well. If the relationship is one person to many >> addresses, then the data model should be exactly that - a >> person_id in the addresses table. You can have an >> "is_primary_address" column in the addresses table, or something >> along those lines, but the enforcement that there is at least one >> address should be done in the application. If you were to take >> that approach, the redundancy in the db would be gone and so >> should the redundancy in the app. >> > Hello, > > Thank you for your quick answer. > > I don''t think there is a design problem in my db (others please > correct me if you don''t think so). There is no redundancy in it, > and I don''t want to enforce there is at least one address for each > person in my db. Actually, address_id can be null. If it isn''t, > then it has to be valid, naturally.I was responding to this (from your initial email): "A person can have one or more addresses, but should at least have one" Even if it''s really 0..n, this is telling me that the foreign key should be in the address table. How do you associate the other addresses to the person? If there is a person_id in the addresses table in addition to the address_id in the people table, that may not look redundant, but to me it is. These relationships should only go one way or the other, unless there is a many to many relationship, in which case that should be expressed in a separate table.> I''ll try to put it another way. For some reason, I want to have a > "country" method in my "person" model. It should look this up in > Address, so I could just do this: > > class Person < ActiveRecord::Base > has_one :address > def country self.address.country if self.address > end end > > This does what I want, but I''d like more. Besides "country", there > are a lot of other methods from Address I''d like to make available > in Person. I''d like to write something to do it automatically. I > tried this: > > for col in Address.content_columns > define method( col.name ) > self.Address.send col.name > end > endHow about this? for col in Address.content_columns name = col.name define_method(name) { return address.send(name) } end
> > I was responding to this (from your initial email): "A person can have > one or more addresses, but should at least have one" > > Even if it''s really 0..n, this is telling me that the foreign key > should be in the address table. > > How do you associate the other addresses to the person? If there is a > person_id in the addresses table in addition to the address_id in the > people table, that may not look redundant, but to me it is. These > relationships should only go one way or the other, unless there is a > many to many relationship, in which case that should be expressed in a > separate table.Ok, there is a person_id in address table too. I could do it like you say, but this won''t help me anyway: I still want a "country" method for Person, which would end up doing some lookup in Address. How can I achieve that? -- ---------------------------------------------------------------------- Yannick Majoros http://www.inma.ucl.ac.be/~majoros Informaticien UCL/INMA-MEMA 4, avenue G. Lema?tre B-1348 Louvain-la-Neuve Tel: +32-10-47.80.10 Fax: +32-10-47.21.80 ---------------------------------------------------------------------- Mon calendrier en ligne : http://www.inma.ucl.ac.be/~majoros/calendar Accents bizarres ? http://www.inma.ucl.ac.be/~majoros/email.html ----------------------------------------------------------------------
Yannick Majoros wrote:>> I was responding to this (from your initial email): "A person can >> have one or more addresses, but should at least have one" >> >> Even if it''s really 0..n, this is telling me that the foreign key >> should be in the address table. >> >> How do you associate the other addresses to the person? If there is a >> person_id in the addresses table in addition to the address_id in the >> people table, that may not look redundant, but to me it is. These >> relationships should only go one way or the other, unless there is a >> many to many relationship, in which case that should be expressed in >> a separate table. > Ok, there is a person_id in address table too. I could do it like you > say, but this won''t help me anyway: I still want a "country" method > for Person, which would end up doing some lookup in Address. How can I > achieve that?A couple of emails back you suggested this: class Person < ActiveRecord::Base has_one :address def country self.address.country if self.address end end If you remove address_id from people, you could do this class Person < ActiveRecord::Base has_many :addresses def country self.addresses[0].country unless addresses[0].empty? end end As for doing it dynamically, I''m not sure what the best approach would be. Did you try my suggestion from the last email? for col in Address.content_columns name = col.name define_method(name) { return address.send(name) } end If that works, then this should work: for col in Address.content_columns name = col.name define_method(name) { return addresses[0].send(name) } unless addresses[0].empty? end I don''t really have any other ideas. Anyone else care to weigh in?
On 7/5/06, Yannick Majoros <majoros@inma.ucl.ac.be> wrote:> > David Chelimsky wrote: > > I''m fairly new to rails, so don''t take my advice. But here it is anyway. > > > > Part of the rails ethos (IMO) is built around enforcing things like > > foreign key constraints in the app, and not in the database. Putting > > an address_id in the people table seems as though it is intended to > > enforce a rule that should be enforced in the application as well. If > > the relationship is one person to many addresses, then the data model > > should be exactly that - a person_id in the addresses table. You can > > have an "is_primary_address" column in the addresses table, or > > something along those lines, but the enforcement that there is at > > least one address should be done in the application. If you were to > > take that approach, the redundancy in the db would be gone and so > > should the redundancy in the app. > > > Hello, > > Thank you for your quick answer. > > I don''t think there is a design problem in my db (others please correct > me if you don''t think so). There is no redundancy in it, and I don''t > want to enforce there is at least one address for each person in my db. > Actually, address_id can be null. If it isn''t, then it has to be valid, > naturally. > > I''ll try to put it another way. For some reason, I want to have a > "country" method in my "person" model. It should look this up in > Address, so I could just do this: > > class Person < ActiveRecord::Base > has_one :address > def country > self.address.country if self.address > end > end > > This does what I want, but I''d like more. Besides "country", there are > a lot of other methods from Address I''d like to make available in > Person. I''d like to write something to do it automatically. I tried this: > > for col in Address.content_columns > define method( col.name ) > self.Address.send col.name > end > end > > But this doesn''t work fully neither, because it is only executed when > it is called, so col.name in the body of the function is not set to the > right column. > > I tried to do it by overriding ActiveRecord::find in my model to have > :include = :address, but mysql does complain because I have some > identical field names in People and Addresses tables (say, > last_update_timestamp ), which makes the JOIN query ambigous.I think it would complain even in model space. If you have a field in address that is the same as that in Person, the persons method will be overwritten with what you''ve suggested above. What you could try that may / my not be what you after is to delegate missing methods to the address object associated with the person.>From David Blacks awsome Ruby For Rails book www.manning.com/black he talksabout setting up delegators. In this case, if a method is missing from Person, delegate whatever method call to the persons address object. so person.country would, provided that there is no method country defined in your person model, provide you with whatever self.address.country would return. I''m not too sure what the ramifications for you will be. If anyone else out there would like to take a guess about whether or not this is a good idea or not, please.... Example delegator setup. class Person < ActiveRecord::Base has_one :address def method_missing( m, *args, &block ) self.address.send(m, *args, &block ) end end As I write this, I''m thinking of another option: I could write de sql> query by hand... But I don''t like this solution for other reasons. > > What could I do? > > Thank you, > > -- > ---------------------------------------------------------------------- > Yannick Majoros http://www.inma.ucl.ac.be/~majoros > Informaticien UCL/INMA-MEMA > 4, avenue G. Lema?tre > B-1348 Louvain-la-Neuve > Tel: +32-10-47.80.10 > Fax: +32-10-47.21.80 > ---------------------------------------------------------------------- > Mon calendrier en ligne : http://www.inma.ucl.ac.be/~majoros/calendar > Accents bizarres ? http://www.inma.ucl.ac.be/~majoros/email.html > ---------------------------------------------------------------------- > > > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060705/2d56f0db/attachment-0001.html
Daniel N wrote:> From David Blacks awsome Ruby For Rails book www.manning.com/black > <http://www.manning.com/black> he talks about setting up delegators. > In this case, if a method is missing from Person, delegate whatever > method call to the persons address object. so person.country would, > provided that there is no method country defined in your person model, > provide you with whatever self.address.country would return. I''m not > too sure what the ramifications for you will be. If anyone else out > there would like to take a guess about whether or not this is a good > idea or not, please.... > > Example delegator setup. > > class Person < ActiveRecord::Base > has_one :address > > def method_missing( m, *args, &block ) > self.address.send(m, *args, &block ) > end > endThank you very much, I think that''s what I''ll do ;-) -- ---------------------------------------------------------------------- Yannick Majoros http://www.inma.ucl.ac.be/~majoros Informaticien UCL/INMA-MEMA 4, avenue G. Lema?tre B-1348 Louvain-la-Neuve Tel: +32-10-47.80.10 Fax: +32-10-47.21.80 ---------------------------------------------------------------------- Mon calendrier en ligne : http://www.inma.ucl.ac.be/~majoros/calendar Accents bizarres ? http://www.inma.ucl.ac.be/~majoros/email.html ---------------------------------------------------------------------- -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3403 bytes Desc: S/MIME Cryptographic Signature Url : http://wrath.rubyonrails.org/pipermail/rails/attachments/20060705/5851bf2d/smime.bin
Yannick Majoros wrote:> Daniel N wrote: >> Example delegator setup. >> >> class Person < ActiveRecord::Base >> has_one :address >> >> def method_missing( m, *args, &block ) >> self.address.send(m, *args, &block ) >> end >> end > Thank you very much, I think that''s what I''ll do ;-)Yannick, would you please report back to the list and let us know if this works for you and, if not, why not? Thanks, David
David Chelimsky wrote:> Yannick Majoros wrote: >> Daniel N wrote: >>> Example delegator setup. >>> >>> class Person < ActiveRecord::Base >>> has_one :address >>> >>> def method_missing( m, *args, &block ) >>> self.address.send(m, *args, &block ) >>> end >>> end >> Thank you very much, I think that''s what I''ll do ;-) > Yannick, would you please report back to the list and let us know if > this works for you and, if not, why not? >Ok, it''s working great. ;-) Thank you very much! Just one more thing to make it perfect: how could I check if a method is present in my other model? I tried with self.address.methods.includes?, but I''ve got really weird results, so I used rescue instead... -- ---------------------------------------------------------------------- Yannick Majoros http://www.inma.ucl.ac.be/~majoros Informaticien UCL/INMA-MEMA 4, avenue G. Lema?tre B-1348 Louvain-la-Neuve Tel: +32-10-47.80.10 Fax: +32-10-47.21.80 ---------------------------------------------------------------------- Mon calendrier en ligne : http://www.inma.ucl.ac.be/~majoros/calendar Accents bizarres ? http://www.inma.ucl.ac.be/~majoros/email.html ---------------------------------------------------------------------- -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3403 bytes Desc: S/MIME Cryptographic Signature Url : http://wrath.rubyonrails.org/pipermail/rails/attachments/20060706/4e51fde7/smime-0001.bin
On Jul 6, 2006, at 4:49 AM, Yannick Majoros wrote:> David Chelimsky wrote: >> Yannick Majoros wrote: >>> Daniel N wrote: >>>> Example delegator setup. >>>> >>>> class Person < ActiveRecord::Base >>>> has_one :address >>>> >>>> def method_missing( m, *args, &block ) >>>> self.address.send(m, *args, &block ) >>>> end >>>> end >>> Thank you very much, I think that''s what I''ll do ;-) >> Yannick, would you please report back to the list and let us know >> if this works for you and, if not, why not? >> > Ok, it''s working great. ;-) Thank you very much!Cool. And thanks to Daniel for the suggestion (and the Black book recommendation).> Just one more thing to make it perfect: how could I check if a > method is present in my other model? I tried with > self.address.methods.includes?, but I''ve got really weird results, > so I used rescue instead...try self.address.methods.include? (no s)
David Chelimsky wrote:> On Jul 6, 2006, at 4:49 AM, Yannick Majoros wrote: >> David Chelimsky wrote: >>> Yannick Majoros wrote: >>>> Daniel N wrote: >>>>> Example delegator setup. >>>>> >>>>> class Person < ActiveRecord::Base >>>>> has_one :address >>>>> >>>>> def method_missing( m, *args, &block ) >>>>> self.address.send(m, *args, &block ) >>>>> end >>>>> end >>>> Thank you very much, I think that''s what I''ll do ;-) >>> Yannick, would you please report back to the list and let us know if >>> this works for you and, if not, why not? >>> >> Ok, it''s working great. ;-) Thank you very much! > > Cool. And thanks to Daniel for the suggestion (and the Black book > recommendation). > >> Just one more thing to make it perfect: how could I check if a method >> is present in my other model? I tried with >> self.address.methods.includes?, but I''ve got really weird results, so >> I used rescue instead... > > try self.address.methods.include? (no s)Ok, that was a type, that''s actually what I did. The problem is that, _sometimes_, when executing method_missing, self.address.includes?( "Country" ) returns nil. The strangest part is naturally that it doesn''t happen all the time. -- ---------------------------------------------------------------------- Yannick Majoros http://www.inma.ucl.ac.be/~majoros Informaticien UCL/INMA-MEMA 4, avenue G. Lema?tre B-1348 Louvain-la-Neuve Tel: +32-10-47.80.10 Fax: +32-10-47.21.80 ---------------------------------------------------------------------- Mon calendrier en ligne : http://www.inma.ucl.ac.be/~majoros/calendar Accents bizarres ? http://www.inma.ucl.ac.be/~majoros/email.html ---------------------------------------------------------------------- -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3403 bytes Desc: S/MIME Cryptographic Signature Url : http://wrath.rubyonrails.org/pipermail/rails/attachments/20060706/08b5dcd3/smime-0001.bin
On 7/6/06, Yannick Majoros <majoros@inma.ucl.ac.be> wrote:> David Chelimsky wrote: > > On Jul 6, 2006, at 4:49 AM, Yannick Majoros wrote: > >> David Chelimsky wrote:> >> Just one more thing to make it perfect: how could I check if a method > >> is present in my other model? I tried with > >> self.address.methods.includes?, but I''ve got really weird results, so > >> I used rescue instead... > > > > try self.address.methods.include? (no s)> The problem is that, _sometimes_, when executing method_missing, > self.address.includes?( "Country" ) returns nil. The strangest part is > naturally that it doesn''t happen all the time.ActiveRecord itself uses method missing to provide access to attributes, so address.country may not be an actual method. Instead of self.address.methods.include? you should use self.address.respond_to? Tom
On 7/6/06, Tom Ward <tom@popdog.net> wrote:> On 7/6/06, Yannick Majoros <majoros@inma.ucl.ac.be> wrote: > > David Chelimsky wrote: > > > On Jul 6, 2006, at 4:49 AM, Yannick Majoros wrote: > > >> David Chelimsky wrote: > > > >> Just one more thing to make it perfect: how could I check if a method > > >> is present in my other model? I tried with > > >> self.address.methods.includes?, but I''ve got really weird results, so > > >> I used rescue instead... > > > > > > try self.address.methods.include? (no s) > > > The problem is that, _sometimes_, when executing method_missing, > > self.address.includes?( "Country" ) returns nil. The strangest part is > > naturally that it doesn''t happen all the time. > > ActiveRecord itself uses method missing to provide access to > attributes, so address.country may not be an actual method. > > Instead of self.address.methods.include? you should use self.address.respond_to?i.e self.address.respond_to ''country''
On 7/6/06, Tom Ward <tom@popdog.net> wrote:> On 7/6/06, Tom Ward <tom@popdog.net> wrote: > > On 7/6/06, Yannick Majoros <majoros@inma.ucl.ac.be> wrote: > > > David Chelimsky wrote: > > > > On Jul 6, 2006, at 4:49 AM, Yannick Majoros wrote: > > > >> David Chelimsky wrote: > > > > > >> Just one more thing to make it perfect: how could I check if a method > > > >> is present in my other model? I tried with > > > >> self.address.methods.includes?, but I''ve got really weird results, so > > > >> I used rescue instead... > > > > > > > > try self.address.methods.include? (no s) > > > > > The problem is that, _sometimes_, when executing method_missing, > > > self.address.includes?( "Country" ) returns nil. The strangest part is > > > naturally that it doesn''t happen all the time. > > > > ActiveRecord itself uses method missing to provide access to > > attributes, so address.country may not be an actual method. > > > > Instead of self.address.methods.include? you should use self.address.respond_to? > > i.e > > self.address.respond_to ''country''Third time lucky: self.address.respond_to? ''country'' Tom
On Jul 6, 2006, at 6:47 AM, Tom Ward wrote:> On 7/6/06, Tom Ward <tom@popdog.net> wrote: >> > > The problem is that, _sometimes_, when executing method_missing, >> > > self.address.includes?( "Country" ) returns nil. The strangest >> part is >> > > naturally that it doesn''t happen all the time. >> > >> > ActiveRecord itself uses method missing to provide access to >> > attributes, so address.country may not be an actual method. >> > >> > Instead of self.address.methods.include? you should use >> self.address.respond_to?Yannick - what are you doing if self.address.respond_to? ''country'' returns false? Just curious.
David Chelimsky wrote:> On Jul 6, 2006, at 6:47 AM, Tom Ward wrote: >> On 7/6/06, Tom Ward <tom@popdog.net> wrote: >>> > > The problem is that, _sometimes_, when executing method_missing, >>> > > self.address.includes?( "Country" ) returns nil. The strangest >>> part is >>> > > naturally that it doesn''t happen all the time. >>> > >>> > ActiveRecord itself uses method missing to provide access to >>> > attributes, so address.country may not be an actual method. >>> > >>> > Instead of self.address.methods.include? you should use >>> self.address.respond_to? >Again, the situation is a bit more complex than what I describe. I could try to give more information by describing a situation which is closer to what I do. Let''s say I have an model whose name is "Action". It''s not really the best example, but it''s the best I could think of. Describing the whole db would take a lot of time. Action has one Person, and Person has one Address (this is not really the case, but...). For some reason, I need to access my_action.Country instead of my_action.person.address.Country to have the country of the person who is performing the action. So, I need to check if Country is a method of Person, and if it isn''t, see if it is a method of Country. Note that by using method_missing, an interesting side-effect is that Action.Country= also works, which I needed anyway ;-) -- ---------------------------------------------------------------------- Yannick Majoros http://www.inma.ucl.ac.be/~majoros Informaticien UCL/INMA-MEMA 4, avenue G. Lema?tre B-1348 Louvain-la-Neuve Tel: +32-10-47.80.10 Fax: +32-10-47.21.80 ---------------------------------------------------------------------- Mon calendrier en ligne : http://www.inma.ucl.ac.be/~majoros/calendar Accents bizarres ? http://www.inma.ucl.ac.be/~majoros/email.html ---------------------------------------------------------------------- -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3403 bytes Desc: S/MIME Cryptographic Signature Url : http://wrath.rubyonrails.org/pipermail/rails/attachments/20060706/f118c12a/smime.bin
Yannick Majoros wrote:> Again, the situation is a bit more complex than what I describe. > > I could try to give more information by describing a situation which > is closer to what I do. > > Let''s say I have an model whose name is "Action". It''s not really the > best example, but it''s the best I could think of. Describing the whole > db would take a lot of time. > > Action has one Person, and Person has one Address (this is not really > the case, but...). > > For some reason, I need to access my_action.Country instead of > my_action.person.address.Country to have the country of the person who > is performing the action. > > So, I need to check if Country is a method of Person, and if it isn''t, > see if it is a method of Country. > > Note that by using method_missing, an interesting side-effect is that > Action.Country= also works, which I needed anyway ;-)Cool. Thanks for taking the time. Cheers, David