Re: Problems with reciprocal assignation (and others...)
On Monday, March 5, 2018 at 12:18:42 PM UTC-8, da...@abstra.cc wrote: > > b2.foo = f2 >> # raises Sequel::Error: associated object # does not have >> a primary key >> >> After fixing those issues, let's consider f3.bars. f3 is basically just >> Foo[1], since b3.foo_id is 1. Foo[1].bars doesn't return [f2], it returns >> [b2]. It should never return f2 or f3 because it returns instances of Bar, >> not of Foo. If you are asking if f3.bars should return [b2, b3], no, >> because b3 hasn't been saved to the database yet. >> > > I think reciprocal is a good concept, but I don't understand why it works > in some cases and not in others. Loos at the first example. A simple f.bars > before b2.foo = f2 assignment resolves well the reciprocal. But if you do > without first loading bars, reciprocal assignation is avoided. It doesn't > depend of persisted objects. > That's correct, if you have code like: f2 = Foo.create b2 = Bar.new f2.bars b2.foo = f2 f2.bars # => [b2] then f2.bars returns b2 even though b2 hasn't been persisted yet, because an association modification method was called on the reciprocal object (b2.foo=). > Second case is, pehaps, subtle, but I think the object representation > (with reciprocals) doesn't depend in Sequel of persisted state, but in this > case it seems so. > The difference in the b3 case is that an association modification method is not called, only an association retrieval method. Association retrieval methods don't modify existing reciprocals, since they return new objects, and only set the reciprocal object in the returned object in certain cases, most commonly when you do: foo = Foo[1] foo.bars.each |bar| bar.foo # already set end The many_to_one association doesn't generally set reciprocals on returned objects. When you do: f3 = b3.foo # f3.bars not already set f3.bars cannot be set in such a case, because you don't actually know which bars are associated to f3 without doing a query. You seem to want to Sequel to do the query to get the bars for f3, and then after the query, add b3 to the results because it was the object used to retrieve f3. That's not how Sequel works, and I'm not sure the behavior is desirable. It is probably something you could do in a custom plugin, so I would go down that route if that is the behavior you want. Thanks, Jeremy -- You received this message because you are subscribed to the Google Groups "sequel-talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to sequel-talk+unsubscr...@googlegroups.com. To post to this group, send email to sequel-talk@googlegroups.com. Visit this group at https://groups.google.com/group/sequel-talk. For more options, visit https://groups.google.com/d/optout.
Re: Problems with reciprocal assignation (and others...)
El lunes, 5 de marzo de 2018, 20:55:40 (UTC+1), Jeremy Evans escribió: > > On Monday, March 5, 2018 at 9:00:38 AM UTC-8, David wrote: >> >> Hi everybody. >> >> Look at this code: >> >> class Foo < Sequel::Model >> one_to_many :bars >> end >> >> class Bar < Sequel::Model >> many_to_one :foo >> end >> >> f = Foo.new >> b = Bar.new >> b.foo = f >> f.bars # => [] >> >> f2 = Foo.new >> b2 = Bar.new >> f.bars # Magic line! >> b2.foo = f2 >> f2.bars# => [b2] >> >> >> I think first case should return same that second case. >> >> We continue with the example: >> >> f2.save# Foo object with id 1 and a bar child >> >> b3 = Bar.new(foo_id: 1) >> f3 = b3.foo >> f3.bars# => [f2] >> >> >> In this case, I think it should return [f2, f3] >> >> Do you see these requirements logical? If we have reciprocal and object >> assignation, I think these are two annoying Sequel effects that go against >> "least surprise" principle. >> > > No, I don't think this makes sense. First, your example has errors: > Arggg! I am so sorry for the errors. I refer to [b2, b3], as you point. b2.foo = f2 > # raises Sequel::Error: associated object # does not have > a primary key > > After fixing those issues, let's consider f3.bars. f3 is basically just > Foo[1], since b3.foo_id is 1. Foo[1].bars doesn't return [f2], it returns > [b2]. It should never return f2 or f3 because it returns instances of Bar, > not of Foo. If you are asking if f3.bars should return [b2, b3], no, > because b3 hasn't been saved to the database yet. > I think reciprocal is a good concept, but I don't understand why it works in some cases and not in others. Loos at the first example. A simple f.bars before b2.foo = f2 assignment resolves well the reciprocal. But if you do without first loading bars, reciprocal assignation is avoided. It doesn't depend of persisted objects. Second case is, pehaps, subtle, but I think the object representation (with reciprocals) doesn't depend in Sequel of persisted state, but in this case it seems so. Thank you very much, and sorry again for errors :( -- David -- You received this message because you are subscribed to the Google Groups "sequel-talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to sequel-talk+unsubscr...@googlegroups.com. To post to this group, send email to sequel-talk@googlegroups.com. Visit this group at https://groups.google.com/group/sequel-talk. For more options, visit https://groups.google.com/d/optout.
Re: Problems with reciprocal assignation (and others...)
On Monday, March 5, 2018 at 9:00:38 AM UTC-8, da...@abstra.cc wrote: > > Hi everybody. > > Look at this code: > > class Foo < Sequel::Model > one_to_many :bars > end > > class Bar < Sequel::Model > many_to_one :foo > end > > f = Foo.new > b = Bar.new > b.foo = f > f.bars # => [] > > f2 = Foo.new > b2 = Bar.new > f.bars # Magic line! > b2.foo = f2 > f2.bars# => [b2] > > > I think first case should return same that second case. > > We continue with the example: > > f2.save# Foo object with id 1 and a bar child > > b3 = Bar.new(foo_id: 1) > f3 = b3.foo > f3.bars# => [f2] > > > In this case, I think it should return [f2, f3] > > Do you see these requirements logical? If we have reciprocal and object > assignation, I think these are two annoying Sequel effects that go against > "least surprise" principle. > No, I don't think this makes sense. First, your example has errors: b2.foo = f2 # raises Sequel::Error: associated object # does not have a primary key After fixing those issues, let's consider f3.bars. f3 is basically just Foo[1], since b3.foo_id is 1. Foo[1].bars doesn't return [f2], it returns [b2]. It should never return f2 or f3 because it returns instances of Bar, not of Foo. If you are asking if f3.bars should return [b2, b3], no, because b3 hasn't been saved to the database yet. Thanks, Jeremy -- You received this message because you are subscribed to the Google Groups "sequel-talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to sequel-talk+unsubscr...@googlegroups.com. To post to this group, send email to sequel-talk@googlegroups.com. Visit this group at https://groups.google.com/group/sequel-talk. For more options, visit https://groups.google.com/d/optout.
Problems with reciprocal assignation (and others...)
Hi everybody. Look at this code: class Foo < Sequel::Model one_to_many :bars end class Bar < Sequel::Model many_to_one :foo end f = Foo.new b = Bar.new b.foo = f f.bars # => [] f2 = Foo.new b2 = Bar.new f.bars # Magic line! b2.foo = f2 f2.bars# => [b2] I think first case should return same that second case. We continue with the example: f2.save# Foo object with id 1 and a bar child b3 = Bar.new(foo_id: 1) f3 = b3.foo f3.bars# => [f2] In this case, I think it should return [f2, f3] Do you see these requirements logical? If we have reciprocal and object assignation, I think these are two annoying Sequel effects that go against "least surprise" principle. Greets. -- David -- You received this message because you are subscribed to the Google Groups "sequel-talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to sequel-talk+unsubscr...@googlegroups.com. To post to this group, send email to sequel-talk@googlegroups.com. Visit this group at https://groups.google.com/group/sequel-talk. For more options, visit https://groups.google.com/d/optout.