Hi, I have two ActiveRecord classes, Player and User. Both underlying tables have a column called email. class User < ActiveRecord::Base end class Player < ActiveRecord::Base belongs_to :user end If the player instance''s user attribute is not nil I want any reference to player.email get or set player.user.email - so I tried this... class Player < ActiveRecord::Base belongs_to :user def email return user.email if !(user.nil? || user.empty?) end end ... but it doesn''t work. When I retreive a relevant player object and try player.email I still get the email address from the player rather than the user. Any ideas where I am going wrong? Martin --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 12/1/06, linus1412 <linus141275-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org> wrote:> > Hi, > > I have two ActiveRecord classes, Player and User. Both underlying > tables have a column called email. > > class User < ActiveRecord::Base > end > > class Player < ActiveRecord::Base > belongs_to :user > end > > If the player instance''s user attribute is not nil I want any reference > to player.email get or set player.user.email - so I tried this... > > class Player < ActiveRecord::Base > belongs_to :user > def email > return user.email if !(user.nil? || user.empty?) > end > end > > ... but it doesn''t work. When I retreive a relevant player object and > try player.email I still get the email address from the player rather > than the user. > > Any ideas where I am going wrong? > > Martin > > > > >Martin, Try this: def email user ? user.email : self[:email] end -- Zack Chandler http://depixelate.com http://trackplace.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Zack, I added... def email user ? user.email : self[:email] end def email=(email) (user ? user : self).email = email end This still doesn''t work, it still brings back the player.email value. Strangely it does work in console. Martin On Dec 1, 11:18 pm, "Zack Chandler" <zackchand...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 12/1/06, linus1412 <linus141...-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org> wrote: > > > > > > > Hi, > > > I have two ActiveRecord classes, Player and User. Both underlying > > tables have a column called email. > > > class User < ActiveRecord::Base > > end > > > class Player < ActiveRecord::Base > > belongs_to :user > > end > > > If the player instance''s user attribute is not nil I want any reference > > to player.email get or set player.user.email - so I tried this... > > > class Player < ActiveRecord::Base > > belongs_to :user > > def email > > return user.email if !(user.nil? || user.empty?) > > end > > end > > > ... but it doesn''t work. When I retreive a relevant player object and > > try player.email I still get the email address from the player rather > > than the user. > > > Any ideas where I am going wrong? > > > MartinMartin, > > Try this: > > def email > user ? user.email : self[:email] > end > > -- > Zack Chandlerhttp://depixelate.comhttp://trackplace.com--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I can reproduce the same behaviour in console by doing p = Player.find 4 p.email => "user-email-gJ1G9MGqaQg@public.gmane.org" # what i want p[:email] => "player-email-gJ1G9MGqaQg@public.gmane.org" # not what i want So are forms populated using second approach? If so this seems to negate accessor overloading as far as form handling is concerned. Martin On Dec 1, 11:50 pm, "linus1412" <linus141...-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org> wrote:> Zack, > > I added... > > def email > user ? user.email : self[:email] > end > > def email=(email) > (user ? user : self).email = email > end > > This still doesn''t work, it still brings back the player.email value. > > Strangely it does work in console. > > Martin > > On Dec 1, 11:18 pm, "Zack Chandler" <zackchand...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > On 12/1/06, linus1412 <linus141...-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org> wrote: > > > > Hi, > > > > I have two ActiveRecord classes, Player and User. Both underlying > > > tables have a column called email. > > > > class User < ActiveRecord::Base > > > end > > > > class Player < ActiveRecord::Base > > > belongs_to :user > > > end > > > > If the player instance''s user attribute is not nil I want any reference > > > to player.email get or set player.user.email - so I tried this... > > > > class Player < ActiveRecord::Base > > > belongs_to :user > > > def email > > > return user.email if !(user.nil? || user.empty?) > > > end > > > end > > > > ... but it doesn''t work. When I retreive a relevant player object and > > > try player.email I still get the email address from the player rather > > > than the user. > > > > Any ideas where I am going wrong? > > > > MartinMartin, > > > Try this: > > > def email > > user ? user.email : self[:email] > > end > > > -- > > Zack Chandlerhttp://depixelate.comhttp://trackplace.com--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 12/1/06, linus1412 <linus141275-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org> wrote:> > I can reproduce the same behaviour in console by doing > > p = Player.find 4 > p.email => "user-email-gJ1G9MGqaQg@public.gmane.org" # what i want > p[:email] => "player-email-gJ1G9MGqaQg@public.gmane.org" # not what i want > > So are forms populated using second approach? > > If so this seems to negate accessor overloading as far as form handling > is concerned. > > Martin > > > On Dec 1, 11:50 pm, "linus1412" <linus141...-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org> wrote: > > Zack, > > > > I added... > > > > def email > > user ? user.email : self[:email] > > end > > > > def email=(email) > > (user ? user : self).email = email > > end > > > > This still doesn''t work, it still brings back the player.email value. > > > > Strangely it does work in console. > > > > Martin > > > > On Dec 1, 11:18 pm, "Zack Chandler" <zackchand...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > On 12/1/06, linus1412 <linus141...-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org> wrote: > > > > > > Hi, > > > > > > I have two ActiveRecord classes, Player and User. Both underlying > > > > tables have a column called email. > > > > > > class User < ActiveRecord::Base > > > > end > > > > > > class Player < ActiveRecord::Base > > > > belongs_to :user > > > > end > > > > > > If the player instance''s user attribute is not nil I want any reference > > > > to player.email get or set player.user.email - so I tried this... > > > > > > class Player < ActiveRecord::Base > > > > belongs_to :user > > > > def email > > > > return user.email if !(user.nil? || user.empty?) > > > > end > > > > end > > > > > > ... but it doesn''t work. When I retreive a relevant player object and > > > > try player.email I still get the email address from the player rather > > > > than the user. > > > > > > Any ideas where I am going wrong? > > > > > > MartinMartin, > > > > > Try this: > > > > > def email > > > user ? user.email : self[:email] > > > end > > > > > -- > > > Zack Chandlerhttp://depixelate.comhttp://trackplace.com > > > > >Martin,> p.email => "user-email-gJ1G9MGqaQg@public.gmane.org" # what i wantThis is good.> p[:email] => "player-email-gJ1G9MGqaQg@public.gmane.org" # not what i wantThis is not good because it bypasses the accessor that you just wrote. The reason is ActiveRecord::Base overrides [] like this: def [](attr_name) read_attribute(attr_name) end ... so it reads the actual column data. Use the first approach. Hope this helps. -- Zack Chandler http://depixelate.com http://trackplace.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Zack, In console I have the choice to use p.email, but when my form displays it is still showing the data from the player object, bypassing my overridden method. I assume that <%= text_field ''player'', ''email'' %> must effectively still call read_attribute(attr_name) rather than use the accessor. Martin --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I think I may have found an answer to this, but it doesn''t seem write. If I override the player_before_type_cast and player_before_type_castmethods it works, as this is what the form calls to get the values to display? This works, but its it ''right''? Martin --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 4 December 2006 03:27, linus1412 wrote:> I think I may have found an answer to this, but it doesn''t seem write. > > If I override the player_before_type_cast and player_before_type_cast> methods it works, as this is what the form calls to get the values to > display? > > This works, but its it ''right''?The problem is that text_field uses *_before_type_cast accessors to get data. I see two solutions: 1. overriding *_before_type_cast accessor (as you described) 2. adding virtual field (that has no underlying column). E.g. in your case this could be done like this: class Player def user_or_player_email return user.email if user self.email end def user_or_player_email=(value) self.email = value end end The trick here is that text_field will use plain value (not _before_type_cast variant) if attribute doesn''t support _before_type_cast accessor. Although, I would prefer using second variant. You could rename players.email column to something like "custom_email" or "player_email" and use "email" as the name of virtual attribute. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2006-Dec-04 10:44 UTC
Re: Overriding default ActiveRecord getter and setter
The other thing is that the various accessor methods are added dynamically when they are first called, which probably means they overwrite the email method you have defined. Fred -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 4 December 2006 13:44, Frederick Cheung wrote:> The other thing is that the various accessor methods are added > dynamically when they are first called, which probably means they > overwrite the email method you have defined.No, dynamically generated accessors for DB columns do not overwrite existing accessors. Dynamic accessor don''t get generated if there is method with the same name already. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---