Hi, I have a model similar Basket shown below. If customer_type is set then it should also set customer to nil. Likewise, if I set customer, it should inspect the customer_type attached to the customer and set accordingly within Basket. However implementing it as below doesn''t seem to work. Am I missing a better way to achieve this? I had also considered using a before_save :set_customer_type kind of thing but felt the code may loose a little readability. I''m coming from a Java world with protected attributes, accessed via domain influence methods, .set_customer, .process_order etc... I wasn''t really sure how best to interpret this into ruby on rails models. class Basket < ActiveRecord::Base belongs_to :customer_type belongs_to :customer def customer=(_customer) write_attribute(:customer, _customer) customer_type = _customer.customer_type unless _customer.nil? end end Thanks, Andrew. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Mark Reginald James
2007-Nov-27 09:00 UTC
Re: Model setters, override attribute=(attribute)?
Andrew Edwards wrote:> I have a model similar Basket shown below. If customer_type is set > then it should also set customer to nil. Likewise, if I set customer, > it should inspect the customer_type attached to the customer and set > accordingly within Basket. However implementing it as below doesn''t > seem to work. > ... > class Basket < ActiveRecord::Base > belongs_to :customer_type > belongs_to :customer > > def customer=(_customer) > write_attribute(:customer, _customer) > customer_type = _customer.customer_type unless _customer.nil? > end > endhttp://groups.google.com/group/rubyonrails-talk/browse_thread/thread/4fe057494c6e23e8 -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ 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 prefer to do this sort of stuff in a callback triggered by .save, such as before_save, after_save, etc. That way it''s not destructive until I "commit" it. Just my .02. On Nov 27, 2007 3:00 AM, Mark Reginald James <mrj-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote:> > Andrew Edwards wrote: > > > I have a model similar Basket shown below. If customer_type is set > > then it should also set customer to nil. Likewise, if I set customer, > > it should inspect the customer_type attached to the customer and set > > accordingly within Basket. However implementing it as below doesn''t > > seem to work. > > ... > > class Basket < ActiveRecord::Base > > belongs_to :customer_type > > belongs_to :customer > > > > def customer=(_customer) > > write_attribute(:customer, _customer) > > customer_type = _customer.customer_type unless _customer.nil? > > end > > end > > > http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/4fe057494c6e23e8 > > -- > We develop, watch us RoR, in numbers too big to ignore. > > > > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Thanks for the thoughts. I like the idea of using the callbacks, I think in many simple cases of setting associated fields it works well. The situations I think I am more referring to are those where you are responding to an event within the model. Such an event would trigger other methods and possibly execute within a database transaction. I suppose in reality these are not often tied to simple updates of a single field, in which case I would probably create a new all-encompassing method anyway. I suppose I''m just used to encapsulating attributes behind setters and model event methods. The AR way of exposing everything probably means a different approach/mindset? Is it okay not to worry about accidentally setting an attribute that really should only be set as part of a larger transaction? --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Make the callbacks public. You can call them when you want. before_save :do_my_stuff def do_my_stuff # does stuff end The thing to remember is that Ruby is not Java, or C#.. Essesntially, everything is public (even private stuff), so encapsulating things behind accessors isn''t really necessary. Often times, it''s not even desireable. When I do user.first_name = "Brian" I don''t want that saved to the db. So when I do foo.bar = "something" I would expect that to work the same way. There''s no real right or wrong answer though :) Do what makes you comfortable. One thing you will find with Ruby is that simple is better, and almost always ends up working better too. That''s what I love about it. On Nov 27, 2007 10:47 AM, Andrew Edwards <andrew-ZYDPpGlny4uS7RsuTa25KztV0T984lsv@public.gmane.org> wrote:> > Thanks for the thoughts. > > I like the idea of using the callbacks, I think in many simple cases > of setting associated fields it works well. The situations I think I > am more referring to are those where you are responding to an event > within the model. Such an event would trigger other methods and > possibly execute within a database transaction. I suppose in reality > these are not often tied to simple updates of a single field, in which > case I would probably create a new all-encompassing method anyway. > > I suppose I''m just used to encapsulating attributes behind setters and > model event methods. The AR way of exposing everything probably means > a different approach/mindset? Is it okay not to worry about > accidentally setting an attribute that really should only be set as > part of a larger transaction? > > > > > >--~--~---------~--~----~------------~-------~--~----~ 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 Nov 26, 6:16 pm, Andrew Edwards wrote> > class Basket < ActiveRecord::Base > > belongs_to :customer_type > belongs_to :customer > > def customer=(_customer) > write_attribute(:customer, _customer) > customer_type = _customer.customer_type unless _customer.nil? > end > > endThe last line in #customer= should be "self.customer_type = ... " Remember, attribute writers cannot stand alone or ruby interprets them as local variables. Most likely, your code is not working because of this bug, not because of a bigger design issue. It''s a nuisance, and has cost me hours of debugging in the past too. regards, Jürgen --~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
MrBanabas-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org
2007-Nov-29 08:12 UTC
Re: Model setters, override attribute=(attribute)?
HIi, I m not really sure and I just would like to mention it: my_basket.customer_id = 1 will not call your setter -- Volker On 28 Nov., 16:48, "Jürgen Strobel" <juergen.strobel.i...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Nov 26, 6:16 pm, Andrew Edwards wrote > > > > > class Basket < ActiveRecord::Base > > > belongs_to :customer_type > > belongs_to :customer > > > def customer=(_customer) > > write_attribute(:customer, _customer) > > customer_type = _customer.customer_type unless _customer.nil? > > end > > > end > > The last line in #customer= should be "self.customer_type = ... " > > Remember, attribute writers cannot stand alone or ruby interprets them > as local variables. Most likely, your code is not working because of > this bug, not because of a bigger design issue. > > It''s a nuisance, and has cost me hours of debugging in the past too. > > regards, Jürgen--~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---