My question is best illustrated by an example. Let''s say we have two simple classes, Order and LineItem defined as follows. class Order < ActiveRecord::Base has_many :line_items end class LineItem < ActiveRecord::Base belongs_to :order end We then open up script/console and load our first order and compare the object IDs of the order that is returned and the order on the first line item. These values never seem to be the same no matter how I obtain the line item.>> o = Order.find(:first) >> l = o.line_items.first >> o.object_id == l.order.object_id=> false The IDs are also not the same if you do this...>> o = Order.find(:first, :include => :line_items) >> l = o.line_items.first >> o.object_id == l.order.object_id=> false Or this...>> o = Order.find(:first, :include => :line_items) >> l = o.line_items.select{ |l| true }.first >> o.object_id == l.order.object_id=> false I noticed this because I have a method in my LineItem class that attempts to update a value on it''s parent Order object like so: def line_total=(value) self.line_total = value self.order.total += self.line_total end The parent Order''s value is never updated because it is a different object instance than the Order that the line item has a reference to. Am I doing something wrong or is this always the case in Rails? Any help would be much appreciated. Regards, Jason -- 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 8/2/07, Jason Fox <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > My question is best illustrated by an example. Let''s say we have two > simple classes, Order and LineItem defined as follows. > > class Order < ActiveRecord::Base > has_many :line_items > end > class LineItem < ActiveRecord::Base > belongs_to :order > end > > We then open up script/console and load our first order and compare the > object IDs of the order that is returned and the order on the first line > item. These values never seem to be the same no matter how I obtain the > line item. > > >> o = Order.find(:first) > >> l = o.line_items.first > >> o.object_id == l.order.object_id > => false > > The IDs are also not the same if you do this... > > >> o = Order.find(:first, :include => :line_items) > >> l = o.line_items.first > >> o.object_id == l.order.object_id > => false > > Or this... > > >> o = Order.find(:first, :include => :line_items) > >> l = o.line_items.select{ |l| true }.first > >> o.object_id == l.order.object_id > => false > > I noticed this because I have a method in my LineItem class that > attempts to update a value on it''s parent Order object like so: > > def line_total=(value) > self.line_total = value > self.order.total += self.line_total > end > > The parent Order''s value is never updated because it is a different > object instance than the Order that the line item has a reference to. > Am I doing something wrong or is this always the case in Rails? Any > help would be much appreciated. > > Regards, > JasonThey''re different ruby objects. But you should be able to do: @order == @line_item.order, since that checks the #id of both records. In your LineItem class, you''ll have to save the order to the database and reload any instances you have in memory to see the changes reflected. -- Rick Olson http://lighthouseapp.com http://weblog.techno-weenie.net http://mephistoblog.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 -~----------~----~----~----~------~----~------~--~---
Rick Olson wrote:> In your LineItem class, you''ll have to save the order to the database > and reload any instances you have in memory to see the changes > reflected.Any idea why it is implemented this way? At the very least I would think that under this scenario...>> o = Order.find(:first, :include => :line_items) >> l = o.line_items.select{ |l| true }.first >> o.object_id == l.order.object_id=> false ... the line item would have a *reference* to the same (Ruby) order object in memory since I''m including the line items in the load AND using an *Array* method to select the object. It seems wasteful to have the line item keep it''s own copy of the order object in memory and makes it difficult to encapsulate functionality cleanly. I don''t mean to shoot the messenger with this post. I''m just wondering if you (or anyone else) could shed some light on the implementation motivations here. Thanks for the quick reply. Regards, Jason -- 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 -~----------~----~----~----~------~----~------~--~---
Jason Fox wrote:> ... the line item would have a *reference* to the same (Ruby) order > object in memory since I''m including the line items in the load AND > using an *Array* method to select the object. It seems wasteful to have > the line item keep it''s own copy of the order object in memory and makes > it difficult to encapsulate functionality cleanly.I just played around with this. It''s even worse than that. After these two lines>> o = Order.find(:first, :include => :line_items) >> l = o.line_items.select{ |l| true }.firstthe l object does not have any order attribute at all. In the third line,>> o.object_id == l.order.object_idl.order actually loads a new order object with a new SQL query. Seems wasteful to me too. -- 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 -~----------~----~----~----~------~----~------~--~---
> Seems wasteful to me too.Proper ORM identity systems are tough to get right, and just not a big deal 90% of the time. Consider this situation: o1 = Order.find 1 o2 = Order.find 1, :include => :line_items Two "equal" orders, but very different because one has the line_items pre-ordered. In your case you can do this: o = Order.find(:first, :include => {:line_items => :order}) But, that generates an SQL query of WTF proportions. I wrote about this in more depth on my blog, going into the query caching stuff in Edge Rails, and an active_record_context plugin I wrote. They''re both very simple implementations of an identity system that help out in most of the common cases: http://activereload.net/2007/5/23/spend-less-time-in-the-database-and-more-time-outdoors -- Rick Olson http://lighthouseapp.com http://weblog.techno-weenie.net http://mephistoblog.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 -~----------~----~----~----~------~----~------~--~---